Compare commits

..

1 Commits

Author SHA1 Message Date
dwelle 4060682c57 dedupe & handle embeddables 2026-02-18 22:57:55 +01:00
114 changed files with 2353 additions and 6500 deletions
@@ -1,3 +1,9 @@
declare global {
interface Window {
debug: typeof Debug;
}
}
const lessPrecise = (num: number, precision = 5) => const lessPrecise = (num: number, precision = 5) =>
parseFloat(num.toPrecision(precision)); parseFloat(num.toPrecision(precision));
@@ -151,70 +157,6 @@ export class Debug {
return ret; return ret;
}; };
}; };
private static CHANGED_CACHE: Record<string, Record<string, unknown>> = {};
public static logChanged(name: string, obj: Record<string, unknown>) {
const prev = Debug.CHANGED_CACHE[name];
Debug.CHANGED_CACHE[name] = obj;
if (!prev) {
return;
}
const allKeys = new Set([...Object.keys(prev), ...Object.keys(obj)]);
const changed: Record<string, { prev: unknown; next: unknown }> = {};
for (const key of allKeys) {
const prevVal = prev[key];
const nextVal = obj[key];
if (!deepEqual(prevVal, nextVal)) {
changed[key] = { prev: prevVal, next: nextVal };
}
}
if (Object.keys(changed).length > 0) {
console.info(`[${name}] changed:`, changed);
}
}
}
function deepEqual(a: unknown, b: unknown): boolean {
if (Object.is(a, b)) {
return true;
}
if (
a === null ||
b === null ||
typeof a !== "object" ||
typeof b !== "object"
) {
return false;
}
if (Array.isArray(a) !== Array.isArray(b)) {
return false;
}
const keysA = Object.keys(a as Record<string, unknown>);
const keysB = Object.keys(b as Record<string, unknown>);
if (keysA.length !== keysB.length) {
return false;
}
for (const key of keysA) {
if (
!deepEqual(
(a as Record<string, unknown>)[key],
(b as Record<string, unknown>)[key],
)
) {
return false;
}
}
return true;
} }
//@ts-ignore
window.debug = Debug;
+15 -14
View File
@@ -240,21 +240,22 @@ export const DEFAULT_ELEMENT_BACKGROUND_COLOR_PALETTE = {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// !!!MUST BE WITHOUT GRAY, TRANSPARENT AND BLACK!!! // !!!MUST BE WITHOUT GRAY, TRANSPARENT AND BLACK!!!
export const getAllColorsSpecificShade = (index: 0 | 1 | 2 | 3 | 4) => [ export const getAllColorsSpecificShade = (index: 0 | 1 | 2 | 3 | 4) =>
// 2nd row [
COLOR_PALETTE.cyan[index], // 2nd row
COLOR_PALETTE.blue[index], COLOR_PALETTE.cyan[index],
COLOR_PALETTE.violet[index], COLOR_PALETTE.blue[index],
COLOR_PALETTE.grape[index], COLOR_PALETTE.violet[index],
COLOR_PALETTE.pink[index], COLOR_PALETTE.grape[index],
COLOR_PALETTE.pink[index],
// 3rd row // 3rd row
COLOR_PALETTE.green[index], COLOR_PALETTE.green[index],
COLOR_PALETTE.teal[index], COLOR_PALETTE.teal[index],
COLOR_PALETTE.yellow[index], COLOR_PALETTE.yellow[index],
COLOR_PALETTE.orange[index], COLOR_PALETTE.orange[index],
COLOR_PALETTE.red[index], COLOR_PALETTE.red[index],
]; ] as const;
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// other helpers // other helpers
-1
View File
@@ -12,4 +12,3 @@ export * from "./url";
export * from "./utils"; export * from "./utils";
export * from "./emitter"; export * from "./emitter";
export * from "./editorInterface"; export * from "./editorInterface";
export { Debug } from "../debug";
+1 -10
View File
@@ -1,7 +1,5 @@
import { average } from "@excalidraw/math"; import { average } from "@excalidraw/math";
import type { GlobalCoord } from "@excalidraw/math";
import type { FontFamilyValues, FontString } from "@excalidraw/element/types"; import type { FontFamilyValues, FontString } from "@excalidraw/element/types";
import type { import type {
@@ -443,7 +441,7 @@ export const viewportCoordsToSceneCoords = (
const x = (clientX - offsetLeft) / zoom.value - scrollX; const x = (clientX - offsetLeft) / zoom.value - scrollX;
const y = (clientY - offsetTop) / zoom.value - scrollY; const y = (clientY - offsetTop) / zoom.value - scrollY;
return { x, y } as GlobalCoord; return { x, y };
}; };
export const sceneCoordsToViewportCoords = ( export const sceneCoordsToViewportCoords = (
@@ -1332,10 +1330,3 @@ export const setFeatureFlag = <F extends keyof FEATURE_FLAGS>(
console.error("unable to set feature flag", e); console.error("unable to set feature flag", e);
} }
}; };
export const oneOf = <N extends string | number | symbol | null, H extends N>(
needle: N,
haystack: readonly H[],
): needle is H => {
return haystack.includes(needle as any);
};
-2
View File
@@ -438,8 +438,6 @@ export class Scene {
options: { options: {
informMutation: boolean; informMutation: boolean;
isDragging: boolean; isDragging: boolean;
isBindingEnabled?: boolean;
isMidpointSnappingEnabled?: boolean;
} = { } = {
informMutation: true, informMutation: true,
isDragging: false, isDragging: false,
+33 -77
View File
@@ -1,4 +1,5 @@
import { import {
KEYS,
arrayToMap, arrayToMap,
getFeatureFlag, getFeatureFlag,
invariant, invariant,
@@ -136,6 +137,12 @@ export const maxBindingDistance_simple = (zoom?: AppState["zoom"]): number => {
); );
}; };
export const shouldEnableBindingForPointerEvent = (
event: React.PointerEvent<HTMLElement>,
) => {
return !event[KEYS.CTRL_OR_CMD];
};
export const isBindingEnabled = (appState: { export const isBindingEnabled = (appState: {
isBindingEnabled: AppState["isBindingEnabled"]; isBindingEnabled: AppState["isBindingEnabled"];
}): boolean => { }): boolean => {
@@ -170,20 +177,8 @@ export const bindOrUnbindBindingElement = (
}, },
); );
bindOrUnbindBindingElementEdge( bindOrUnbindBindingElementEdge(arrow, start, "start", scene);
arrow, bindOrUnbindBindingElementEdge(arrow, end, "end", scene);
start,
"start",
scene,
appState.isBindingEnabled,
);
bindOrUnbindBindingElementEdge(
arrow,
end,
"end",
scene,
appState.isBindingEnabled,
);
if (start.focusPoint || end.focusPoint) { if (start.focusPoint || end.focusPoint) {
// If the strategy dictates a focus point override, then // If the strategy dictates a focus point override, then
// update the arrow points to point to the focus point. // update the arrow points to point to the focus point.
@@ -226,21 +221,12 @@ const bindOrUnbindBindingElementEdge = (
{ mode, element, focusPoint }: BindingStrategy, { mode, element, focusPoint }: BindingStrategy,
startOrEnd: "start" | "end", startOrEnd: "start" | "end",
scene: Scene, scene: Scene,
shouldSnapToOutline = true,
): void => { ): void => {
if (mode === null) { if (mode === null) {
// null means break the binding // null means break the binding
unbindBindingElement(arrow, startOrEnd, scene); unbindBindingElement(arrow, startOrEnd, scene);
} else if (mode !== undefined) { } else if (mode !== undefined) {
bindBindingElement( bindBindingElement(arrow, element, mode, startOrEnd, scene, focusPoint);
arrow,
element,
mode,
startOrEnd,
scene,
focusPoint,
shouldSnapToOutline,
);
} }
}; };
@@ -812,7 +798,6 @@ const getBindingStrategyForDraggingBindingElementEndpoints_simple = (
startDragged ? "start" : "end", startDragged ? "start" : "end",
elementsMap, elementsMap,
appState.zoom, appState.zoom,
appState.isMidpointSnappingEnabled,
) || globalPoint, ) || globalPoint,
} }
: { mode: null }; : { mode: null };
@@ -857,7 +842,6 @@ const getBindingStrategyForDraggingBindingElementEndpoints_simple = (
startDragged ? "end" : "start", startDragged ? "end" : "start",
elementsMap, elementsMap,
appState.zoom, appState.zoom,
appState.isMidpointSnappingEnabled,
) || otherEndpoint, ) || otherEndpoint,
} }
: { mode: undefined } : { mode: undefined }
@@ -1021,7 +1005,6 @@ export const bindBindingElement = (
startOrEnd: "start" | "end", startOrEnd: "start" | "end",
scene: Scene, scene: Scene,
focusPoint?: GlobalPoint, focusPoint?: GlobalPoint,
shouldSnapToOutline = true,
): void => { ): void => {
const elementsMap = scene.getNonDeletedElementsMap(); const elementsMap = scene.getNonDeletedElementsMap();
@@ -1036,7 +1019,6 @@ export const bindBindingElement = (
hoveredElement, hoveredElement,
startOrEnd, startOrEnd,
elementsMap, elementsMap,
shouldSnapToOutline,
), ),
}; };
} else { } else {
@@ -1370,7 +1352,6 @@ export const bindPointToSnapToElementOutline = (
startOrEnd: "start" | "end", startOrEnd: "start" | "end",
elementsMap: ElementsMap, elementsMap: ElementsMap,
customIntersector?: LineSegment<GlobalPoint>, customIntersector?: LineSegment<GlobalPoint>,
isMidpointSnappingEnabled = true,
): GlobalPoint => { ): GlobalPoint => {
const elbowed = isElbowArrow(arrowElement); const elbowed = isElbowArrow(arrowElement);
const point = LinearElementEditor.getPointAtIndexGlobalCoordinates( const point = LinearElementEditor.getPointAtIndexGlobalCoordinates(
@@ -1410,9 +1391,13 @@ export const bindPointToSnapToElementOutline = (
const isHorizontal = headingIsHorizontal( const isHorizontal = headingIsHorizontal(
headingForPointFromElement(bindableElement, aabb, point), headingForPointFromElement(bindableElement, aabb, point),
); );
const snapPoint = isMidpointSnappingEnabled const snapPoint = snapToMid(
? snapToMid(bindableElement, elementsMap, edgePoint, 0.05, arrowElement) bindableElement,
: undefined; elementsMap,
edgePoint,
0.05,
arrowElement,
);
const resolved = snapPoint || point; const resolved = snapPoint || point;
const otherPoint = pointFrom<GlobalPoint>( const otherPoint = pointFrom<GlobalPoint>(
isHorizontal ? bindableCenter[0] : resolved[0], isHorizontal ? bindableCenter[0] : resolved[0],
@@ -1791,13 +1776,10 @@ export const updateBoundPoint = (
); );
const otherArrowPoint = LinearElementEditor.getPointAtIndexGlobalCoordinates( const otherArrowPoint = LinearElementEditor.getPointAtIndexGlobalCoordinates(
arrow, arrow,
startOrEnd === "startBinding" ? 1 : -2, startOrEnd === "startBinding" ? -1 : 0,
elementsMap, elementsMap,
); );
const otherFocusPointOrArrowPoint = const otherFocusPointOrArrowPoint = otherFocusPoint || otherArrowPoint;
arrow.points.length === 2
? otherFocusPoint || otherArrowPoint
: otherArrowPoint;
const intersector = const intersector =
otherFocusPointOrArrowPoint && otherFocusPointOrArrowPoint &&
lineSegment(focusPoint, otherFocusPointOrArrowPoint); lineSegment(focusPoint, otherFocusPointOrArrowPoint);
@@ -1907,8 +1889,6 @@ export const calculateFixedPointForElbowArrowBinding = (
hoveredElement: ExcalidrawBindableElement, hoveredElement: ExcalidrawBindableElement,
startOrEnd: "start" | "end", startOrEnd: "start" | "end",
elementsMap: ElementsMap, elementsMap: ElementsMap,
shouldSnapToOutline = true,
isMidpointSnappingEnabled = true,
): { fixedPoint: FixedPoint } => { ): { fixedPoint: FixedPoint } => {
const bounds = [ const bounds = [
hoveredElement.x, hoveredElement.x,
@@ -1916,20 +1896,12 @@ export const calculateFixedPointForElbowArrowBinding = (
hoveredElement.x + hoveredElement.width, hoveredElement.x + hoveredElement.width,
hoveredElement.y + hoveredElement.height, hoveredElement.y + hoveredElement.height,
] as Bounds; ] as Bounds;
const snappedPoint = shouldSnapToOutline const snappedPoint = bindPointToSnapToElementOutline(
? bindPointToSnapToElementOutline( linearElement,
linearElement, hoveredElement,
hoveredElement, startOrEnd,
startOrEnd, elementsMap,
elementsMap, );
undefined,
isMidpointSnappingEnabled,
)
: LinearElementEditor.getPointAtIndexGlobalCoordinates(
linearElement,
startOrEnd === "start" ? 0 : -1,
elementsMap,
);
const globalMidPoint = pointFrom( const globalMidPoint = pointFrom(
bounds[0] + (bounds[2] - bounds[0]) / 2, bounds[0] + (bounds[2] - bounds[0]) / 2,
bounds[1] + (bounds[3] - bounds[1]) / 2, bounds[1] + (bounds[3] - bounds[1]) / 2,
@@ -2475,37 +2447,21 @@ export const getArrowLocalFixedPoints = (
]; ];
}; };
export const isFixedPoint = ( export const normalizeFixedPoint = <T extends FixedPoint | null>(
fixedPoint: any,
): fixedPoint is FixedPointBinding["fixedPoint"] => {
return (
Array.isArray(fixedPoint) &&
fixedPoint.length === 2 &&
fixedPoint.every((coord) => Number.isFinite(coord))
);
};
export const normalizeFixedPoint = <T extends FixedPoint>(
fixedPoint: T, fixedPoint: T,
): FixedPoint => { ): T extends null ? null : FixedPoint => {
if (!isFixedPoint(fixedPoint)) {
return [0.5001, 0.5001];
}
const EPSILON = 0.0001;
// Do not allow a precise 0.5 for fixed point ratio // Do not allow a precise 0.5 for fixed point ratio
// to avoid jumping arrow heading due to floating point imprecision // to avoid jumping arrow heading due to floating point imprecision
if ( if (
Math.abs(fixedPoint[0] - 0.5) < EPSILON || fixedPoint &&
Math.abs(fixedPoint[1] - 0.5) < EPSILON (Math.abs(fixedPoint[0] - 0.5) < 0.0001 ||
Math.abs(fixedPoint[1] - 0.5) < 0.0001)
) { ) {
return fixedPoint.map((ratio) => return fixedPoint.map((ratio) =>
Math.abs(ratio - 0.5) < EPSILON ? 0.5001 : ratio, Math.abs(ratio - 0.5) < 0.0001 ? 0.5001 : ratio,
) as FixedPoint; ) as T extends null ? null : FixedPoint;
} }
return fixedPoint as any as T extends null ? null : FixedPoint;
return fixedPoint;
}; };
type Side = type Side =
+2 -14
View File
@@ -915,8 +915,6 @@ export const updateElbowArrowPoints = (
}, },
options?: { options?: {
isDragging?: boolean; isDragging?: boolean;
isBindingEnabled?: boolean;
isMidpointSnappingEnabled?: boolean;
}, },
): ElementUpdate<ExcalidrawElbowArrowElement> => { ): ElementUpdate<ExcalidrawElbowArrowElement> => {
if (arrow.points.length < 2) { if (arrow.points.length < 2) {
@@ -1204,8 +1202,6 @@ const getElbowArrowData = (
options?: { options?: {
isDragging?: boolean; isDragging?: boolean;
zoom?: AppState["zoom"]; zoom?: AppState["zoom"];
isBindingEnabled?: boolean;
isMidpointSnappingEnabled?: boolean;
}, },
) => { ) => {
const origStartGlobalPoint: GlobalPoint = pointTranslate< const origStartGlobalPoint: GlobalPoint = pointTranslate<
@@ -1219,7 +1215,7 @@ const getElbowArrowData = (
let hoveredStartElement = null; let hoveredStartElement = null;
let hoveredEndElement = null; let hoveredEndElement = null;
if (options?.isDragging && options?.isBindingEnabled !== false) { if (options?.isDragging) {
const elements = Array.from(elementsMap.values()); const elements = Array.from(elementsMap.values());
hoveredStartElement = hoveredStartElement =
getHoveredElement( getHoveredElement(
@@ -1259,8 +1255,6 @@ const getElbowArrowData = (
hoveredStartElement, hoveredStartElement,
elementsMap, elementsMap,
options?.isDragging, options?.isDragging,
options?.isBindingEnabled,
options?.isMidpointSnappingEnabled,
); );
const endGlobalPoint = getGlobalPoint( const endGlobalPoint = getGlobalPoint(
{ {
@@ -1276,8 +1270,6 @@ const getElbowArrowData = (
hoveredEndElement, hoveredEndElement,
elementsMap, elementsMap,
options?.isDragging, options?.isDragging,
options?.isBindingEnabled,
options?.isMidpointSnappingEnabled,
); );
const startHeading = getBindPointHeading( const startHeading = getBindPointHeading(
startGlobalPoint, startGlobalPoint,
@@ -2221,18 +2213,14 @@ const getGlobalPoint = (
element?: ExcalidrawBindableElement | null, element?: ExcalidrawBindableElement | null,
elementsMap?: ElementsMap, elementsMap?: ElementsMap,
isDragging?: boolean, isDragging?: boolean,
isBindingEnabled = true,
isMidpointSnappingEnabled = true,
): GlobalPoint => { ): GlobalPoint => {
if (isDragging) { if (isDragging) {
if (isBindingEnabled && element && elementsMap) { if (element && elementsMap) {
return bindPointToSnapToElementOutline( return bindPointToSnapToElementOutline(
arrow, arrow,
element, element,
startOrEnd, startOrEnd,
elementsMap, elementsMap,
undefined,
isMidpointSnappingEnabled,
); );
} }
+18 -50
View File
@@ -359,20 +359,11 @@ export class LinearElementEditor {
linearElementEditor, linearElementEditor,
); );
LinearElementEditor.movePoints( LinearElementEditor.movePoints(element, app.scene, positions, {
element, startBinding: updates?.startBinding,
app.scene, endBinding: updates?.endBinding,
positions, moveMidPointsWithElement: updates?.moveMidPointsWithElement,
{ });
startBinding: updates?.startBinding,
endBinding: updates?.endBinding,
moveMidPointsWithElement: updates?.moveMidPointsWithElement,
},
{
isBindingEnabled: app.state.isBindingEnabled,
isMidpointSnappingEnabled: app.state.isMidpointSnappingEnabled,
},
);
// Set the suggested binding from the updates if available // Set the suggested binding from the updates if available
if (isBindingElement(element, false)) { if (isBindingElement(element, false)) {
if (isBindingEnabled(app.state)) { if (isBindingEnabled(app.state)) {
@@ -427,7 +418,6 @@ export class LinearElementEditor {
"start", "start",
elementsMap, elementsMap,
app.state.zoom, app.state.zoom,
app.state.isMidpointSnappingEnabled,
) )
: linearElementEditor.initialState.altFocusPoint, : linearElementEditor.initialState.altFocusPoint,
}, },
@@ -548,20 +538,11 @@ export class LinearElementEditor {
linearElementEditor, linearElementEditor,
); );
LinearElementEditor.movePoints( LinearElementEditor.movePoints(element, app.scene, positions, {
element, startBinding: updates?.startBinding,
app.scene, endBinding: updates?.endBinding,
positions, moveMidPointsWithElement: updates?.moveMidPointsWithElement,
{ });
startBinding: updates?.startBinding,
endBinding: updates?.endBinding,
moveMidPointsWithElement: updates?.moveMidPointsWithElement,
},
{
isBindingEnabled: app.state.isBindingEnabled,
isMidpointSnappingEnabled: app.state.isMidpointSnappingEnabled,
},
);
// Set the suggested binding from the updates if available // Set the suggested binding from the updates if available
if (isBindingElement(element, false)) { if (isBindingElement(element, false)) {
@@ -655,7 +636,6 @@ export class LinearElementEditor {
"start", "start",
elementsMap, elementsMap,
app.state.zoom, app.state.zoom,
app.state.isMidpointSnappingEnabled,
) )
: linearElementEditor.initialState.altFocusPoint, : linearElementEditor.initialState.altFocusPoint,
}, },
@@ -1544,10 +1524,6 @@ export class LinearElementEditor {
endBinding?: FixedPointBinding | null; endBinding?: FixedPointBinding | null;
moveMidPointsWithElement?: boolean | null; moveMidPointsWithElement?: boolean | null;
}, },
options?: {
isBindingEnabled?: boolean;
isMidpointSnappingEnabled?: boolean;
},
) { ) {
const { points } = element; const { points } = element;
@@ -1616,8 +1592,6 @@ export class LinearElementEditor {
otherUpdates, otherUpdates,
{ {
isDragging: Array.from(pointUpdates.values()).some((t) => t.isDragging), isDragging: Array.from(pointUpdates.values()).some((t) => t.isDragging),
isBindingEnabled: options?.isBindingEnabled,
isMidpointSnappingEnabled: options?.isMidpointSnappingEnabled,
}, },
); );
} }
@@ -1732,8 +1706,6 @@ export class LinearElementEditor {
isDragging?: boolean; isDragging?: boolean;
zoom?: AppState["zoom"]; zoom?: AppState["zoom"];
sceneElementsMap?: NonDeletedSceneElementsMap; sceneElementsMap?: NonDeletedSceneElementsMap;
isBindingEnabled?: boolean;
isMidpointSnappingEnabled?: boolean;
}, },
) { ) {
if (isElbowArrow(element)) { if (isElbowArrow(element)) {
@@ -1754,8 +1726,6 @@ export class LinearElementEditor {
scene.mutateElement(element, updates, { scene.mutateElement(element, updates, {
informMutation: true, informMutation: true,
isDragging: options?.isDragging ?? false, isDragging: options?.isDragging ?? false,
isBindingEnabled: options?.isBindingEnabled,
isMidpointSnappingEnabled: options?.isMidpointSnappingEnabled,
}); });
} else { } else {
// TODO do we need to get precise coords here just to calc centers? // TODO do we need to get precise coords here just to calc centers?
@@ -2175,16 +2145,14 @@ const pointDraggingUpdates = (
suggestedBinding: suggestedBindingElement suggestedBinding: suggestedBindingElement
? { ? {
element: suggestedBindingElement, element: suggestedBindingElement,
midPoint: app.state.isMidpointSnappingEnabled midPoint: snapToMid(
? snapToMid( suggestedBindingElement,
suggestedBindingElement, elementsMap,
elementsMap, pointFrom<GlobalPoint>(
pointFrom<GlobalPoint>( scenePointerX - linearElementEditor.pointerOffset.x,
scenePointerX - linearElementEditor.pointerOffset.x, scenePointerY - linearElementEditor.pointerOffset.y,
scenePointerY - linearElementEditor.pointerOffset.y, ),
), ),
)
: undefined,
} }
: null, : null,
}, },
-2
View File
@@ -40,8 +40,6 @@ export const mutateElement = <TElement extends Mutable<ExcalidrawElement>>(
updates: ElementUpdate<TElement>, updates: ElementUpdate<TElement>,
options?: { options?: {
isDragging?: boolean; isDragging?: boolean;
isBindingEnabled?: boolean;
isMidpointSnappingEnabled?: boolean;
}, },
) => { ) => {
let didChange = false; let didChange = false;
+1 -1
View File
@@ -15,7 +15,7 @@ import type {
ValueOf, ValueOf,
} from "@excalidraw/common/utility-types"; } from "@excalidraw/common/utility-types";
export type ChartType = "bar" | "line" | "radar"; export type ChartType = "bar" | "line";
export type FillStyle = "hachure" | "cross-hatch" | "solid" | "zigzag"; export type FillStyle = "hachure" | "cross-hatch" | "solid" | "zigzag";
export type FontFamilyKeys = keyof typeof FONT_FAMILY; export type FontFamilyKeys = keyof typeof FONT_FAMILY;
export type FontFamilyValues = typeof FONT_FAMILY[FontFamilyKeys]; export type FontFamilyValues = typeof FONT_FAMILY[FontFamilyKeys];
+8 -11
View File
@@ -659,23 +659,20 @@ export const projectFixedPointOntoDiagonal = (
startOrEnd: "start" | "end", startOrEnd: "start" | "end",
elementsMap: ElementsMap, elementsMap: ElementsMap,
zoom: AppState["zoom"], zoom: AppState["zoom"],
isMidpointSnappingEnabled: boolean = true,
): GlobalPoint | null => { ): GlobalPoint | null => {
invariant(arrow.points.length >= 2, "Arrow must have at least two points"); invariant(arrow.points.length >= 2, "Arrow must have at least two points");
if (arrow.width < 3 && arrow.height < 3) { if (arrow.width < 3 && arrow.height < 3) {
return null; return null;
} }
if (isMidpointSnappingEnabled) { const sideMidPoint = getSnapOutlineMidPoint(
const sideMidPoint = getSnapOutlineMidPoint( point,
point, element,
element, elementsMap,
elementsMap, zoom,
zoom, );
); if (sideMidPoint) {
if (sideMidPoint) { return sideMidPoint;
return sideMidPoint;
}
} }
// Do the projection onto the diagonals (or center lines // Do the projection onto the diagonals (or center lines
@@ -118,6 +118,7 @@ export const actionClearCanvas = register({
gridStep: appState.gridStep, gridStep: appState.gridStep,
gridModeEnabled: appState.gridModeEnabled, gridModeEnabled: appState.gridModeEnabled,
stats: appState.stats, stats: appState.stats,
pasteDialog: appState.pasteDialog,
activeTool: activeTool:
appState.activeTool.type === "image" appState.activeTool.type === "image"
? { ? {
@@ -1830,7 +1830,6 @@ export const actionChangeArrowType = register<keyof typeof ARROW_TYPE>({
startElement, startElement,
"start", "start",
elementsMap, elementsMap,
appState.isBindingEnabled,
), ),
} }
: null; : null;
@@ -1844,7 +1843,6 @@ export const actionChangeArrowType = register<keyof typeof ARROW_TYPE>({
endElement, endElement,
"end", "end",
elementsMap, elementsMap,
appState.isBindingEnabled,
), ),
} }
: null; : null;
@@ -1,26 +0,0 @@
import { CaptureUpdateAction } from "@excalidraw/element";
import { register } from "./register";
export const actionToggleArrowBinding = register({
name: "arrowBinding",
label: "labels.arrowBinding",
viewMode: false,
trackEvent: {
category: "canvas",
predicate: (appState) => appState.bindingPreference === "disabled",
},
perform(elements, appState) {
const newPreference =
appState.bindingPreference === "enabled" ? "disabled" : "enabled";
return {
appState: {
...appState,
bindingPreference: newPreference,
isBindingEnabled: newPreference === "enabled",
},
captureUpdate: CaptureUpdateAction.NEVER,
};
},
checked: (appState) => appState.bindingPreference === "enabled",
});
@@ -1,23 +0,0 @@
import { CaptureUpdateAction } from "@excalidraw/element";
import { register } from "./register";
export const actionToggleMidpointSnapping = register({
name: "midpointSnapping",
label: "labels.midpointSnapping",
viewMode: false,
trackEvent: {
category: "canvas",
predicate: (appState) => !appState.isMidpointSnappingEnabled,
},
perform(elements, appState) {
return {
appState: {
...appState,
isMidpointSnappingEnabled: !this.checked!(appState),
},
captureUpdate: CaptureUpdateAction.NEVER,
};
},
checked: (appState) => appState.isMidpointSnappingEnabled,
});
-2
View File
@@ -79,8 +79,6 @@ export {
export { actionToggleGridMode } from "./actionToggleGridMode"; export { actionToggleGridMode } from "./actionToggleGridMode";
export { actionToggleZenMode } from "./actionToggleZenMode"; export { actionToggleZenMode } from "./actionToggleZenMode";
export { actionToggleObjectsSnapMode } from "./actionToggleObjectsSnapMode"; export { actionToggleObjectsSnapMode } from "./actionToggleObjectsSnapMode";
export { actionToggleArrowBinding } from "./actionToggleArrowBinding";
export { actionToggleMidpointSnapping } from "./actionToggleMidpointSnapping";
export { actionToggleStats } from "./actionToggleStats"; export { actionToggleStats } from "./actionToggleStats";
export { actionUnbindText, actionBindText } from "./actionBoundText"; export { actionUnbindText, actionBindText } from "./actionBoundText";
-2
View File
@@ -59,8 +59,6 @@ export type ActionName =
| "gridMode" | "gridMode"
| "zenMode" | "zenMode"
| "objectsSnapMode" | "objectsSnapMode"
| "arrowBinding"
| "midpointSnapping"
| "stats" | "stats"
| "changeStrokeColor" | "changeStrokeColor"
| "changeBackgroundColor" | "changeBackgroundColor"
+5 -5
View File
@@ -27,6 +27,7 @@ export const getDefaultAppState = (): Omit<
showWelcomeScreen: false, showWelcomeScreen: false,
theme: THEME.LIGHT, theme: THEME.LIGHT,
collaborators: new Map(), collaborators: new Map(),
currentChartType: "bar",
currentItemBackgroundColor: DEFAULT_ELEMENT_PROPS.backgroundColor, currentItemBackgroundColor: DEFAULT_ELEMENT_PROPS.backgroundColor,
currentItemEndArrowhead: "arrow", currentItemEndArrowhead: "arrow",
currentItemFillStyle: DEFAULT_ELEMENT_PROPS.fillStyle, currentItemFillStyle: DEFAULT_ELEMENT_PROPS.fillStyle,
@@ -70,8 +71,6 @@ export const getDefaultAppState = (): Omit<
gridStep: DEFAULT_GRID_STEP, gridStep: DEFAULT_GRID_STEP,
gridModeEnabled: false, gridModeEnabled: false,
isBindingEnabled: true, isBindingEnabled: true,
bindingPreference: "enabled",
isMidpointSnappingEnabled: true,
defaultSidebarDockedPreference: false, defaultSidebarDockedPreference: false,
isLoading: false, isLoading: false,
isResizing: false, isResizing: false,
@@ -84,6 +83,7 @@ export const getDefaultAppState = (): Omit<
openPopup: null, openPopup: null,
openSidebar: null, openSidebar: null,
openDialog: null, openDialog: null,
pasteDialog: { shown: false, data: null },
previousSelectedElementIds: {}, previousSelectedElementIds: {},
resizingElement: null, resizingElement: null,
scrolledOutside: false, scrolledOutside: false,
@@ -150,6 +150,7 @@ const APP_STATE_STORAGE_CONF = (<
showWelcomeScreen: { browser: true, export: false, server: false }, showWelcomeScreen: { browser: true, export: false, server: false },
theme: { browser: true, export: false, server: false }, theme: { browser: true, export: false, server: false },
collaborators: { browser: false, export: false, server: false }, collaborators: { browser: false, export: false, server: false },
currentChartType: { browser: true, export: false, server: false },
currentItemBackgroundColor: { browser: true, export: false, server: false }, currentItemBackgroundColor: { browser: true, export: false, server: false },
currentItemEndArrowhead: { browser: true, export: false, server: false }, currentItemEndArrowhead: { browser: true, export: false, server: false },
currentItemFillStyle: { browser: true, export: false, server: false }, currentItemFillStyle: { browser: true, export: false, server: false },
@@ -192,9 +193,7 @@ const APP_STATE_STORAGE_CONF = (<
gridStep: { browser: true, export: true, server: true }, gridStep: { browser: true, export: true, server: true },
gridModeEnabled: { browser: true, export: true, server: true }, gridModeEnabled: { browser: true, export: true, server: true },
height: { browser: false, export: false, server: false }, height: { browser: false, export: false, server: false },
isBindingEnabled: { browser: true, export: false, server: false }, isBindingEnabled: { browser: false, export: false, server: false },
bindingPreference: { browser: true, export: false, server: false },
isMidpointSnappingEnabled: { browser: true, export: false, server: false },
defaultSidebarDockedPreference: { defaultSidebarDockedPreference: {
browser: true, browser: true,
export: false, export: false,
@@ -213,6 +212,7 @@ const APP_STATE_STORAGE_CONF = (<
openPopup: { browser: false, export: false, server: false }, openPopup: { browser: false, export: false, server: false },
openSidebar: { browser: true, export: false, server: false }, openSidebar: { browser: true, export: false, server: false },
openDialog: { browser: false, export: false, server: false }, openDialog: { browser: false, export: false, server: false },
pasteDialog: { browser: false, export: false, server: false },
previousSelectedElementIds: { browser: true, export: false, server: false }, previousSelectedElementIds: { browser: true, export: false, server: false },
resizingElement: { browser: false, export: false, server: false }, resizingElement: { browser: false, export: false, server: false },
scrolledOutside: { browser: true, export: false, server: false }, scrolledOutside: { browser: true, export: false, server: false },
File diff suppressed because it is too large Load Diff
+481
View File
@@ -0,0 +1,481 @@
import { pointFrom } from "@excalidraw/math";
import {
COLOR_PALETTE,
DEFAULT_CHART_COLOR_INDEX,
getAllColorsSpecificShade,
DEFAULT_FONT_FAMILY,
DEFAULT_FONT_SIZE,
VERTICAL_ALIGN,
randomId,
isDevEnv,
FONT_SIZES,
} from "@excalidraw/common";
import {
newTextElement,
newLinearElement,
newElement,
} from "@excalidraw/element";
import type { Radians } from "@excalidraw/math";
import type { NonDeletedExcalidrawElement } from "@excalidraw/element/types";
export type ChartElements = readonly NonDeletedExcalidrawElement[];
const BAR_WIDTH = 32;
const BAR_GAP = 12;
const BAR_HEIGHT = 256;
const GRID_OPACITY = 50;
export interface Spreadsheet {
title: string | null;
labels: string[] | null;
values: number[];
}
export const NOT_SPREADSHEET = "NOT_SPREADSHEET";
export const VALID_SPREADSHEET = "VALID_SPREADSHEET";
type ParseSpreadsheetResult =
| { type: typeof NOT_SPREADSHEET; reason: string }
| { type: typeof VALID_SPREADSHEET; spreadsheet: Spreadsheet };
/**
* @private exported for testing
*/
export const tryParseNumber = (s: string): number | null => {
const match = /^([-+]?)[$€£¥₩]?([-+]?)([\d.,]+)[%]?$/.exec(s);
if (!match) {
return null;
}
return parseFloat(`${(match[1] || match[2]) + match[3]}`.replace(/,/g, ""));
};
const isNumericColumn = (lines: string[][], columnIndex: number) =>
lines.slice(1).every((line) => tryParseNumber(line[columnIndex]) !== null);
/**
* @private exported for testing
*/
export const tryParseCells = (cells: string[][]): ParseSpreadsheetResult => {
const numCols = cells[0].length;
if (numCols > 2) {
return { type: NOT_SPREADSHEET, reason: "More than 2 columns" };
}
if (numCols === 1) {
if (!isNumericColumn(cells, 0)) {
return { type: NOT_SPREADSHEET, reason: "Value is not numeric" };
}
const hasHeader = tryParseNumber(cells[0][0]) === null;
const values = (hasHeader ? cells.slice(1) : cells).map((line) =>
tryParseNumber(line[0]),
);
if (values.length < 2) {
return { type: NOT_SPREADSHEET, reason: "Less than two rows" };
}
return {
type: VALID_SPREADSHEET,
spreadsheet: {
title: hasHeader ? cells[0][0] : null,
labels: null,
values: values as number[],
},
};
}
const labelColumnNumeric = isNumericColumn(cells, 0);
const valueColumnNumeric = isNumericColumn(cells, 1);
if (!labelColumnNumeric && !valueColumnNumeric) {
return { type: NOT_SPREADSHEET, reason: "Value is not numeric" };
}
const [labelColumnIndex, valueColumnIndex] = valueColumnNumeric
? [0, 1]
: [1, 0];
const hasHeader = tryParseNumber(cells[0][valueColumnIndex]) === null;
const rows = hasHeader ? cells.slice(1) : cells;
if (rows.length < 2) {
return { type: NOT_SPREADSHEET, reason: "Less than 2 rows" };
}
return {
type: VALID_SPREADSHEET,
spreadsheet: {
title: hasHeader ? cells[0][valueColumnIndex] : null,
labels: rows.map((row) => row[labelColumnIndex]),
values: rows.map((row) => tryParseNumber(row[valueColumnIndex])!),
},
};
};
const transposeCells = (cells: string[][]) => {
const nextCells: string[][] = [];
for (let col = 0; col < cells[0].length; col++) {
const nextCellRow: string[] = [];
for (let row = 0; row < cells.length; row++) {
nextCellRow.push(cells[row][col]);
}
nextCells.push(nextCellRow);
}
return nextCells;
};
export const tryParseSpreadsheet = (text: string): ParseSpreadsheetResult => {
// Copy/paste from excel, spreadsheets, tsv, csv.
// For now we only accept 2 columns with an optional header
// Check for tab separated values
let lines = text
.trim()
.split("\n")
.map((line) => line.trim().split("\t"));
// Check for comma separated files
if (lines.length && lines[0].length !== 2) {
lines = text
.trim()
.split("\n")
.map((line) => line.trim().split(","));
}
if (lines.length === 0) {
return { type: NOT_SPREADSHEET, reason: "No values" };
}
const numColsFirstLine = lines[0].length;
const isSpreadsheet = lines.every((line) => line.length === numColsFirstLine);
if (!isSpreadsheet) {
return {
type: NOT_SPREADSHEET,
reason: "All rows don't have same number of columns",
};
}
const result = tryParseCells(lines);
if (result.type !== VALID_SPREADSHEET) {
const transposedResults = tryParseCells(transposeCells(lines));
if (transposedResults.type === VALID_SPREADSHEET) {
return transposedResults;
}
}
return result;
};
const bgColors = getAllColorsSpecificShade(DEFAULT_CHART_COLOR_INDEX);
// Put all the common properties here so when the whole chart is selected
// the properties dialog shows the correct selected values
const commonProps = {
fillStyle: "hachure",
fontFamily: DEFAULT_FONT_FAMILY,
fontSize: DEFAULT_FONT_SIZE,
opacity: 100,
roughness: 1,
strokeColor: COLOR_PALETTE.black,
roundness: null,
strokeStyle: "solid",
strokeWidth: 1,
verticalAlign: VERTICAL_ALIGN.MIDDLE,
locked: false,
} as const;
const getChartDimensions = (spreadsheet: Spreadsheet) => {
const chartWidth =
(BAR_WIDTH + BAR_GAP) * spreadsheet.values.length + BAR_GAP;
const chartHeight = BAR_HEIGHT + BAR_GAP * 2;
return { chartWidth, chartHeight };
};
const chartXLabels = (
spreadsheet: Spreadsheet,
x: number,
y: number,
groupId: string,
backgroundColor: string,
): ChartElements => {
return (
spreadsheet.labels?.map((label, index) => {
return newTextElement({
groupIds: [groupId],
backgroundColor,
...commonProps,
text: label.length > 8 ? `${label.slice(0, 5)}...` : label,
x: x + index * (BAR_WIDTH + BAR_GAP) + BAR_GAP * 2,
y: y + BAR_GAP / 2,
width: BAR_WIDTH,
angle: 5.87 as Radians,
fontSize: FONT_SIZES.sm,
textAlign: "center",
verticalAlign: "top",
});
}) || []
);
};
const chartYLabels = (
spreadsheet: Spreadsheet,
x: number,
y: number,
groupId: string,
backgroundColor: string,
): ChartElements => {
const minYLabel = newTextElement({
groupIds: [groupId],
backgroundColor,
...commonProps,
x: x - BAR_GAP,
y: y - BAR_GAP,
text: "0",
textAlign: "right",
});
const maxYLabel = newTextElement({
groupIds: [groupId],
backgroundColor,
...commonProps,
x: x - BAR_GAP,
y: y - BAR_HEIGHT - minYLabel.height / 2,
text: Math.max(...spreadsheet.values).toLocaleString(),
textAlign: "right",
});
return [minYLabel, maxYLabel];
};
const chartLines = (
spreadsheet: Spreadsheet,
x: number,
y: number,
groupId: string,
backgroundColor: string,
): ChartElements => {
const { chartWidth, chartHeight } = getChartDimensions(spreadsheet);
const xLine = newLinearElement({
backgroundColor,
groupIds: [groupId],
...commonProps,
type: "line",
x,
y,
width: chartWidth,
points: [pointFrom(0, 0), pointFrom(chartWidth, 0)],
});
const yLine = newLinearElement({
backgroundColor,
groupIds: [groupId],
...commonProps,
type: "line",
x,
y,
height: chartHeight,
points: [pointFrom(0, 0), pointFrom(0, -chartHeight)],
});
const maxLine = newLinearElement({
backgroundColor,
groupIds: [groupId],
...commonProps,
type: "line",
x,
y: y - BAR_HEIGHT - BAR_GAP,
strokeStyle: "dotted",
width: chartWidth,
opacity: GRID_OPACITY,
points: [pointFrom(0, 0), pointFrom(chartWidth, 0)],
});
return [xLine, yLine, maxLine];
};
// For the maths behind it https://excalidraw.com/#json=6320864370884608,O_5xfD-Agh32tytHpRJx1g
const chartBaseElements = (
spreadsheet: Spreadsheet,
x: number,
y: number,
groupId: string,
backgroundColor: string,
debug?: boolean,
): ChartElements => {
const { chartWidth, chartHeight } = getChartDimensions(spreadsheet);
const title = spreadsheet.title
? newTextElement({
backgroundColor,
groupIds: [groupId],
...commonProps,
text: spreadsheet.title,
x: x + chartWidth / 2,
y: y - BAR_HEIGHT - BAR_GAP * 2 - DEFAULT_FONT_SIZE,
roundness: null,
textAlign: "center",
})
: null;
const debugRect = debug
? newElement({
backgroundColor,
groupIds: [groupId],
...commonProps,
type: "rectangle",
x,
y: y - chartHeight,
width: chartWidth,
height: chartHeight,
strokeColor: COLOR_PALETTE.black,
fillStyle: "solid",
opacity: 6,
})
: null;
return [
...(debugRect ? [debugRect] : []),
...(title ? [title] : []),
...chartXLabels(spreadsheet, x, y, groupId, backgroundColor),
...chartYLabels(spreadsheet, x, y, groupId, backgroundColor),
...chartLines(spreadsheet, x, y, groupId, backgroundColor),
];
};
const chartTypeBar = (
spreadsheet: Spreadsheet,
x: number,
y: number,
): ChartElements => {
const max = Math.max(...spreadsheet.values);
const groupId = randomId();
const backgroundColor = bgColors[Math.floor(Math.random() * bgColors.length)];
const bars = spreadsheet.values.map((value, index) => {
const barHeight = (value / max) * BAR_HEIGHT;
return newElement({
backgroundColor,
groupIds: [groupId],
...commonProps,
type: "rectangle",
x: x + index * (BAR_WIDTH + BAR_GAP) + BAR_GAP,
y: y - barHeight - BAR_GAP,
width: BAR_WIDTH,
height: barHeight,
});
});
return [
...bars,
...chartBaseElements(
spreadsheet,
x,
y,
groupId,
backgroundColor,
isDevEnv(),
),
];
};
const chartTypeLine = (
spreadsheet: Spreadsheet,
x: number,
y: number,
): ChartElements => {
const max = Math.max(...spreadsheet.values);
const groupId = randomId();
const backgroundColor = bgColors[Math.floor(Math.random() * bgColors.length)];
let index = 0;
const points = [];
for (const value of spreadsheet.values) {
const cx = index * (BAR_WIDTH + BAR_GAP);
const cy = -(value / max) * BAR_HEIGHT;
points.push([cx, cy]);
index++;
}
const maxX = Math.max(...points.map((element) => element[0]));
const maxY = Math.max(...points.map((element) => element[1]));
const minX = Math.min(...points.map((element) => element[0]));
const minY = Math.min(...points.map((element) => element[1]));
const line = newLinearElement({
backgroundColor,
groupIds: [groupId],
...commonProps,
type: "line",
x: x + BAR_GAP + BAR_WIDTH / 2,
y: y - BAR_GAP,
height: maxY - minY,
width: maxX - minX,
strokeWidth: 2,
points: points as any,
});
const dots = spreadsheet.values.map((value, index) => {
const cx = index * (BAR_WIDTH + BAR_GAP) + BAR_GAP / 2;
const cy = -(value / max) * BAR_HEIGHT + BAR_GAP / 2;
return newElement({
backgroundColor,
groupIds: [groupId],
...commonProps,
fillStyle: "solid",
strokeWidth: 2,
type: "ellipse",
x: x + cx + BAR_WIDTH / 2,
y: y + cy - BAR_GAP * 2,
width: BAR_GAP,
height: BAR_GAP,
});
});
const lines = spreadsheet.values.map((value, index) => {
const cx = index * (BAR_WIDTH + BAR_GAP) + BAR_GAP / 2;
const cy = (value / max) * BAR_HEIGHT + BAR_GAP / 2 + BAR_GAP;
return newLinearElement({
backgroundColor,
groupIds: [groupId],
...commonProps,
type: "line",
x: x + cx + BAR_WIDTH / 2 + BAR_GAP / 2,
y: y - cy,
height: cy,
strokeStyle: "dotted",
opacity: GRID_OPACITY,
points: [pointFrom(0, 0), pointFrom(0, cy)],
});
});
return [
...chartBaseElements(
spreadsheet,
x,
y,
groupId,
backgroundColor,
isDevEnv(),
),
line,
...lines,
...dots,
];
};
export const renderSpreadsheet = (
chartType: string,
spreadsheet: Spreadsheet,
x: number,
y: number,
): ChartElements => {
if (chartType === "line") {
return chartTypeLine(spreadsheet, x, y);
}
return chartTypeBar(spreadsheet, x, y);
};
-103
View File
@@ -1,103 +0,0 @@
import { isDevEnv } from "@excalidraw/common";
import { newElement } from "@excalidraw/element";
import { commonProps } from "./charts.constants";
import {
chartBaseElements,
chartXLabels,
createSeriesLegend,
getBackgroundColor,
getCartesianChartLayout,
getChartDimensions,
getColorOffset,
getRotatedTextElementBottom,
getSeriesColors,
} from "./charts.helpers";
import type { ChartElements, Spreadsheet } from "./charts.types";
export const renderBarChart = (
spreadsheet: Spreadsheet,
x: number,
y: number,
colorSeed?: number,
): ChartElements => {
const series = spreadsheet.series;
const layout = getCartesianChartLayout("bar", series.length);
const max = Math.max(
1,
...series.flatMap((seriesData) =>
seriesData.values.map((value) => Math.max(0, value)),
),
);
const colorOffset = getColorOffset(colorSeed);
const backgroundColor = getBackgroundColor(colorOffset);
const seriesColors = getSeriesColors(series.length, colorOffset);
const interBarGap =
series.length > 1
? Math.max(1, Math.floor(layout.gap / (series.length + 1)))
: 0;
const barWidth =
series.length > 1
? Math.max(
2,
(layout.slotWidth - interBarGap * (series.length - 1)) /
series.length,
)
: layout.slotWidth;
const clusterWidth =
series.length * barWidth + interBarGap * (series.length - 1);
const clusterOffset = (layout.slotWidth - clusterWidth) / 2;
const bars = series[0].values.flatMap((_, categoryIndex) =>
series.map((seriesData, seriesIndex) => {
const value = Math.max(0, seriesData.values[categoryIndex] ?? 0);
const barHeight = (value / max) * layout.chartHeight;
const barColor =
series.length > 1 ? seriesColors[seriesIndex] : backgroundColor;
return newElement({
backgroundColor: barColor,
...commonProps,
type: "rectangle",
fillStyle: series.length > 1 ? "solid" : commonProps.fillStyle,
strokeColor: series.length > 1 ? barColor : commonProps.strokeColor,
x:
x +
categoryIndex * (layout.slotWidth + layout.gap) +
layout.gap +
clusterOffset +
seriesIndex * (barWidth + interBarGap),
y: y - barHeight - layout.gap,
width: barWidth,
height: barHeight,
});
}),
);
const baseElements = chartBaseElements(
spreadsheet,
x,
y,
backgroundColor,
layout,
max,
isDevEnv(),
);
const xLabels = chartXLabels(spreadsheet, x, y, backgroundColor, layout);
const xLabelsBottomY = Math.max(
y + layout.gap / 2,
...xLabels.map((label) => getRotatedTextElementBottom(label)),
);
const { chartWidth } = getChartDimensions(spreadsheet, layout);
const seriesLegend = createSeriesLegend(
series,
seriesColors,
x + chartWidth / 2,
xLabelsBottomY,
y + layout.gap * 5,
backgroundColor,
);
return [...baseElements, ...bars, ...seriesLegend];
};
@@ -1,63 +0,0 @@
import {
COLOR_PALETTE,
DEFAULT_FONT_FAMILY,
DEFAULT_FONT_SIZE,
VERTICAL_ALIGN,
} from "@excalidraw/common";
import type { Radians } from "@excalidraw/math";
export const CARTESIAN_BASE_SLOT_WIDTH = 44;
export const CARTESIAN_BAR_SLOT_EXTRA_PER_SERIES = 22;
export const CARTESIAN_BAR_SLOT_EXTRA_MAX = 66;
export const CARTESIAN_LINE_SLOT_WIDTH = 48;
export const CARTESIAN_GAP = 14;
export const CARTESIAN_BAR_HEIGHT = 304;
export const CARTESIAN_LINE_HEIGHT = 320;
export const CARTESIAN_LABEL_ROTATION = 5.87 as Radians;
export const CARTESIAN_LABEL_MIN_WIDTH = 28;
export const CARTESIAN_LABEL_SLOT_PADDING = 4;
export const CARTESIAN_LABEL_AXIS_CLEARANCE = 2;
export const CARTESIAN_LABEL_MAX_WIDTH_BUFFER = 10;
export const CARTESIAN_LABEL_ROTATED_WIDTH_BUFFER = 10;
export const CARTESIAN_LABEL_OVERFLOW_PREFERENCE_BUFFER = 8;
export const BAR_GAP = 12;
export const BAR_HEIGHT = 256;
export const GRID_OPACITY = 10;
export const RADAR_GRID_LEVELS = 4;
export const RADAR_LABEL_OFFSET = BAR_GAP * 2;
export const RADAR_PADDING = BAR_GAP * 2;
export const RADAR_SINGLE_SERIES_LOG_SCALE_THRESHOLD = 100;
export const RADAR_AXIS_LABEL_MAX_WIDTH = 140;
export const RADAR_AXIS_LABEL_ALIGNMENT_THRESHOLD = 0.35;
export const RADAR_AXIS_LABEL_CLEARANCE = BAR_GAP / 2;
export const RADAR_LEGEND_SWATCH_SIZE = 20;
export const RADAR_LEGEND_ITEM_GAP = BAR_GAP * 2;
export const RADAR_LEGEND_TEXT_GAP = BAR_GAP;
// Put all common chart element properties here so properties dialog
// shows stable values when selecting chart groups.
export const commonProps = {
fillStyle: "hachure",
fontFamily: DEFAULT_FONT_FAMILY,
fontSize: DEFAULT_FONT_SIZE,
opacity: 100,
roughness: 1,
strokeColor: COLOR_PALETTE.black,
roundness: null,
strokeStyle: "solid",
strokeWidth: 1,
verticalAlign: VERTICAL_ALIGN.MIDDLE,
locked: false,
} as const;
export type CartesianChartType = "bar" | "line";
export type CartesianChartLayout = {
slotWidth: number;
gap: number;
chartHeight: number;
xLabelMaxWidth: number;
};
@@ -1,865 +0,0 @@
import { pointFrom } from "@excalidraw/math";
import {
COLOR_PALETTE,
DEFAULT_CHART_COLOR_INDEX,
FONT_FAMILY,
FONT_SIZES,
ROUNDNESS,
DEFAULT_FONT_SIZE,
getAllColorsSpecificShade,
getFontString,
getLineHeight,
ROUGHNESS,
} from "@excalidraw/common";
import {
getApproxMinLineWidth,
measureText,
newElement,
newLinearElement,
newTextElement,
wrapText,
} from "@excalidraw/element";
import type {
ChartType,
ExcalidrawTextElement,
} from "@excalidraw/element/types";
import type { NonDeletedExcalidrawElement } from "@excalidraw/element/types";
import {
BAR_GAP,
CARTESIAN_BAR_HEIGHT,
CARTESIAN_BASE_SLOT_WIDTH,
CARTESIAN_BAR_SLOT_EXTRA_MAX,
CARTESIAN_BAR_SLOT_EXTRA_PER_SERIES,
CARTESIAN_GAP,
CARTESIAN_LABEL_AXIS_CLEARANCE,
CARTESIAN_LABEL_MAX_WIDTH_BUFFER,
CARTESIAN_LABEL_MIN_WIDTH,
CARTESIAN_LABEL_OVERFLOW_PREFERENCE_BUFFER,
CARTESIAN_LABEL_ROTATED_WIDTH_BUFFER,
CARTESIAN_LABEL_ROTATION,
CARTESIAN_LABEL_SLOT_PADDING,
CARTESIAN_LINE_HEIGHT,
CARTESIAN_LINE_SLOT_WIDTH,
GRID_OPACITY,
RADAR_AXIS_LABEL_ALIGNMENT_THRESHOLD,
RADAR_AXIS_LABEL_CLEARANCE,
RADAR_AXIS_LABEL_MAX_WIDTH,
RADAR_LABEL_OFFSET,
RADAR_LEGEND_ITEM_GAP,
RADAR_LEGEND_SWATCH_SIZE,
RADAR_LEGEND_TEXT_GAP,
RADAR_PADDING,
RADAR_SINGLE_SERIES_LOG_SCALE_THRESHOLD,
BAR_HEIGHT,
commonProps,
type CartesianChartLayout,
type CartesianChartType,
} from "./charts.constants";
import type {
ChartElements,
Spreadsheet,
SpreadsheetSeries,
} from "./charts.types";
const bgColors = getAllColorsSpecificShade(DEFAULT_CHART_COLOR_INDEX);
const getSpreadsheetDimensionCount = (spreadsheet: Spreadsheet) =>
spreadsheet.labels?.length ?? spreadsheet.series[0]?.values.length ?? 0;
export const isSpreadsheetValidForChartType = (
spreadsheet: Spreadsheet | null,
chartType: ChartType,
) => {
if (!spreadsheet) {
return false;
}
const dimensionCount = getSpreadsheetDimensionCount(spreadsheet);
if (dimensionCount < 2) {
return false;
}
if (chartType === "radar") {
return dimensionCount >= 3;
}
return true;
};
const getSeriesAwareSlotWidth = (
baseSlotWidth: number,
seriesCount: number,
) => {
const extraSlotWidth =
seriesCount <= 1
? 0
: Math.min(
CARTESIAN_BAR_SLOT_EXTRA_MAX,
(seriesCount - 1) * CARTESIAN_BAR_SLOT_EXTRA_PER_SERIES,
);
return baseSlotWidth + extraSlotWidth;
};
export const getCartesianChartLayout = (
chartType: CartesianChartType,
seriesCount: number,
): CartesianChartLayout => {
if (chartType === "line") {
const slotWidth = getSeriesAwareSlotWidth(
CARTESIAN_LINE_SLOT_WIDTH,
seriesCount,
);
return {
slotWidth,
gap: CARTESIAN_GAP,
chartHeight: CARTESIAN_LINE_HEIGHT,
xLabelMaxWidth:
slotWidth + CARTESIAN_GAP * 3 + CARTESIAN_LABEL_MAX_WIDTH_BUFFER,
};
}
const slotWidth = getSeriesAwareSlotWidth(
CARTESIAN_BASE_SLOT_WIDTH,
seriesCount,
);
return {
slotWidth,
gap: CARTESIAN_GAP,
chartHeight: CARTESIAN_BAR_HEIGHT,
xLabelMaxWidth:
slotWidth + CARTESIAN_GAP * 3 + CARTESIAN_LABEL_MAX_WIDTH_BUFFER,
};
};
export const getChartDimensions = (
spreadsheet: Spreadsheet,
layout: CartesianChartLayout,
) => {
const chartWidth =
(layout.slotWidth + layout.gap) * spreadsheet.series[0].values.length +
layout.gap;
const chartHeight = layout.chartHeight + layout.gap * 2;
return { chartWidth, chartHeight };
};
export const getRadarDimensions = () => {
const chartWidth = BAR_HEIGHT + RADAR_PADDING * 2;
const chartHeight = BAR_HEIGHT + RADAR_PADDING * 2;
return { chartWidth, chartHeight };
};
const getCircularDistance = (
firstIndex: number,
secondIndex: number,
paletteSize: number,
) => {
const absoluteDistance = Math.abs(firstIndex - secondIndex);
return Math.min(absoluteDistance, paletteSize - absoluteDistance);
};
export const getSeriesColors = (
seriesCount: number,
colorOffset: number,
): readonly string[] => {
if (seriesCount <= 0 || bgColors.length === 0) {
return [];
}
const paletteSize = bgColors.length;
const startIndex = ((colorOffset % paletteSize) + paletteSize) % paletteSize;
const selectedIndices = [startIndex];
const maxUniqueColors = Math.min(seriesCount, paletteSize);
const availableIndices = new Set(
Array.from({ length: paletteSize }, (_, index) => index).filter(
(index) => index !== startIndex,
),
);
while (selectedIndices.length < maxUniqueColors) {
let bestIndex = -1;
let bestMinDistance = -1;
let bestAverageDistance = -1;
for (const candidateIndex of availableIndices) {
const distances = selectedIndices.map((selectedIndex) =>
getCircularDistance(candidateIndex, selectedIndex, paletteSize),
);
const minDistance = Math.min(...distances);
const averageDistance =
distances.reduce((total, distance) => total + distance, 0) /
distances.length;
if (
minDistance > bestMinDistance ||
(minDistance === bestMinDistance &&
averageDistance > bestAverageDistance)
) {
bestIndex = candidateIndex;
bestMinDistance = minDistance;
bestAverageDistance = averageDistance;
}
}
selectedIndices.push(bestIndex);
availableIndices.delete(bestIndex);
}
return Array.from(
{ length: seriesCount },
(_, index) => bgColors[selectedIndices[index % selectedIndices.length]],
);
};
export const getColorOffset = (colorSeed?: number) => {
if (bgColors.length === 0) {
return 0;
}
if (typeof colorSeed !== "number" || !Number.isFinite(colorSeed)) {
return Math.floor(Math.random() * bgColors.length);
}
const seedText = colorSeed.toString();
let hash = 0;
for (let index = 0; index < seedText.length; index++) {
hash = (hash * 31 + seedText.charCodeAt(index)) | 0;
}
return Math.abs(hash) % bgColors.length;
};
export const getBackgroundColor = (colorOffset: number) =>
bgColors[colorOffset];
export const getRadarValueScale = (
series: SpreadsheetSeries[],
_labelsLength: number,
) => {
const allValues = series.flatMap((s) =>
s.values.map((value) => Math.max(0, value)),
);
const positiveValues = allValues.filter((value) => value > 0);
const max = Math.max(1, ...allValues);
const minPositive =
positiveValues.length > 0 ? Math.min(...positiveValues) : 1;
const useLogScale =
series.length === 1 &&
minPositive > 0 &&
max / minPositive >= RADAR_SINGLE_SERIES_LOG_SCALE_THRESHOLD;
return {
renderSteps: false,
normalize: (value: number, _axisIndex: number) => {
const safeValue = Math.max(0, value);
return useLogScale
? Math.log10(safeValue + 1) / Math.log10(max + 1)
: safeValue / max;
},
};
};
const shouldWrapRadarText = (text: string) => /\s/.test(text.trim());
export const getRadarDisplayText = (
text: string,
fontString: ReturnType<typeof getFontString>,
maxWidth: number,
) => {
return shouldWrapRadarText(text)
? wrapText(text, fontString, maxWidth)
: text;
};
export const createRadarAxisLabels = (
labels: readonly string[],
angles: readonly number[],
centerX: number,
centerY: number,
radius: number,
backgroundColor: string,
): {
axisLabels: ChartElements;
axisLabelTopY: number;
axisLabelBottomY: number;
} => {
const fontFamily = FONT_FAMILY.Excalifont;
const fontSize = FONT_SIZES.sm;
const lineHeight = getLineHeight(fontFamily);
const fontString = getFontString({ fontFamily, fontSize });
const baseLabelWidth = Math.min(
RADAR_AXIS_LABEL_MAX_WIDTH,
radius * (labels.length > 8 ? 0.56 : 0.72),
);
const minLabelWidth = getApproxMinLineWidth(fontString, lineHeight);
const axisLabels = labels.map((label, index) => {
const angle = angles[index];
const longestWordWidth = Math.max(
0,
...label
.trim()
.split(/\s+/)
.filter(Boolean)
.map((word) => measureText(word, fontString, lineHeight).width),
);
const maxLabelWidth = Math.max(
minLabelWidth,
baseLabelWidth,
longestWordWidth,
);
const displayLabel = getRadarDisplayText(label, fontString, maxLabelWidth);
const metrics = measureText(displayLabel, fontString, lineHeight);
const cos = Math.cos(angle);
const sin = Math.sin(angle);
const textAlign: "left" | "center" | "right" =
cos > RADAR_AXIS_LABEL_ALIGNMENT_THRESHOLD
? "left"
: cos < -RADAR_AXIS_LABEL_ALIGNMENT_THRESHOLD
? "right"
: "center";
// Keep labels outside the radar ring by projecting text extents
// onto the axis direction.
const centerAlignedXExtent = textAlign === "center" ? metrics.width / 2 : 0;
const projectedExtent =
Math.abs(cos) * centerAlignedXExtent +
Math.abs(sin) * (metrics.height / 2);
const radialOffset =
RADAR_LABEL_OFFSET + projectedExtent + RADAR_AXIS_LABEL_CLEARANCE;
const anchorX = centerX + cos * (radius + radialOffset);
const anchorY = centerY + sin * (radius + radialOffset);
const yNudge =
sin > RADAR_AXIS_LABEL_ALIGNMENT_THRESHOLD
? BAR_GAP / 3
: sin < -RADAR_AXIS_LABEL_ALIGNMENT_THRESHOLD
? -BAR_GAP / 3
: 0;
return newTextElement({
backgroundColor,
...commonProps,
text: displayLabel,
originalText: label,
x: anchorX,
y: anchorY + yNudge,
fontFamily,
fontSize,
lineHeight,
textAlign,
verticalAlign: "middle",
});
});
const axisLabelTopY = Math.min(...axisLabels.map((axisLabel) => axisLabel.y));
const axisLabelBottomY = Math.max(
...axisLabels.map((axisLabel) => axisLabel.y + axisLabel.height),
);
return { axisLabels, axisLabelTopY, axisLabelBottomY };
};
export const createSeriesLegend = (
series: SpreadsheetSeries[],
seriesColors: readonly string[],
centerX: number,
minLegendTopY: number,
fallbackLegendY: number,
backgroundColor: string,
): ChartElements => {
if (series.length <= 1) {
return [];
}
const fontFamily = FONT_FAMILY["Lilita One"];
const fontSize = FONT_SIZES.lg;
const lineHeight = getLineHeight(fontFamily);
const fontString = getFontString({ fontFamily, fontSize });
const legendItems = series.map((seriesItem, index) => {
const label = seriesItem.title?.trim() || `Series ${index + 1}`;
const displayLabel = getRadarDisplayText(label, fontString, BAR_HEIGHT);
const metrics = measureText(displayLabel, fontString, lineHeight);
const itemWidth =
RADAR_LEGEND_SWATCH_SIZE + RADAR_LEGEND_TEXT_GAP + metrics.width;
return {
label,
displayLabel,
color: seriesColors[index],
width: itemWidth,
height: metrics.height,
};
});
const maxLegendHalfHeight = Math.max(
RADAR_LEGEND_SWATCH_SIZE / 2,
...legendItems.map((item) => item.height / 2),
);
const legendY = Math.max(
fallbackLegendY,
minLegendTopY + maxLegendHalfHeight + RADAR_LABEL_OFFSET,
);
const pillPaddingX = RADAR_LEGEND_ITEM_GAP;
const pillPaddingY = RADAR_LEGEND_SWATCH_SIZE * 0.6;
const totalLegendWidth =
legendItems.reduce((total, item) => total + item.width, 0) +
RADAR_LEGEND_ITEM_GAP * Math.max(0, legendItems.length - 1);
const pillWidth = totalLegendWidth + pillPaddingX * 2;
const pillHeight = maxLegendHalfHeight * 2 + pillPaddingY * 2;
const legendElements: NonDeletedExcalidrawElement[] = [];
// rounded pill background
legendElements.push(
newElement({
...commonProps,
backgroundColor: "transparent",
type: "rectangle",
fillStyle: "solid",
strokeColor: COLOR_PALETTE.black,
x: centerX - pillWidth / 2,
y: legendY - pillHeight / 2,
width: pillWidth,
height: pillHeight,
roughness: ROUGHNESS.architect,
roundness: { type: ROUNDNESS.PROPORTIONAL_RADIUS },
}),
);
let cursorX = centerX - totalLegendWidth / 2;
legendItems.forEach((item) => {
// solid filled swatch
legendElements.push(
newElement({
...commonProps,
backgroundColor: item.color,
type: "rectangle",
x: cursorX,
y: legendY - RADAR_LEGEND_SWATCH_SIZE / 2,
width: RADAR_LEGEND_SWATCH_SIZE,
height: RADAR_LEGEND_SWATCH_SIZE,
fillStyle: "solid",
strokeColor: item.color,
roughness: ROUGHNESS.architect,
roundness: { type: ROUNDNESS.PROPORTIONAL_RADIUS },
}),
);
// label in default (black) color
legendElements.push(
newTextElement({
...commonProps,
text: item.displayLabel,
originalText: item.label,
autoResize: false,
x: cursorX + RADAR_LEGEND_SWATCH_SIZE + RADAR_LEGEND_TEXT_GAP,
y: legendY,
fontFamily,
fontSize,
lineHeight,
textAlign: "left",
verticalAlign: "middle",
}),
);
cursorX += item.width + RADAR_LEGEND_ITEM_GAP;
});
return legendElements;
};
const ellipsifyTextToWidth = (
text: string,
maxWidth: number,
fontString: ReturnType<typeof getFontString>,
lineHeight: ExcalidrawTextElement["lineHeight"],
) => {
if (measureText(text, fontString, lineHeight).width <= maxWidth) {
return text;
}
let end = text.length;
while (end > 1) {
const candidate = `${text.slice(0, end)}...`;
if (measureText(candidate, fontString, lineHeight).width <= maxWidth) {
return candidate;
}
end--;
}
return text[0] ? `${text[0]}...` : text;
};
const wrapOrEllipsifyTextToWidth = (
text: string,
maxWidth: number,
fontString: ReturnType<typeof getFontString>,
lineHeight: ExcalidrawTextElement["lineHeight"],
) => {
if (measureText(text, fontString, lineHeight).width <= maxWidth) {
return { wrapped: false, text };
}
const words = text.trim().split(/\s+/).filter(Boolean);
if (words.length > 1) {
const hasLongWord = words.some((word) => {
return measureText(word, fontString, lineHeight).width > maxWidth;
});
if (
!hasLongWord &&
maxWidth >= getApproxMinLineWidth(fontString, lineHeight)
) {
return { wrapped: true, text: wrapText(text, fontString, maxWidth) };
}
}
return {
wrapped: false,
text: ellipsifyTextToWidth(text, maxWidth, fontString, lineHeight),
};
};
const getRotatedBoundingBox = (
width: number,
height: number,
angle: number,
) => {
const cos = Math.abs(Math.cos(angle));
const sin = Math.abs(Math.sin(angle));
return {
width: width * cos + height * sin,
height: width * sin + height * cos,
};
};
type CartesianAxisLabelSpec = {
originalText: string;
text: string;
wrapped: boolean;
metrics: ReturnType<typeof measureText>;
rotatedWidth: number;
rotatedHeight: number;
};
const isEllipsifiedLabel = (text: string) => text.includes("...");
const getCartesianAxisLabelSpec = (
label: string,
maxLabelWidth: number,
maxRotatedWidth: number,
fontString: ReturnType<typeof getFontString>,
lineHeight: ExcalidrawTextElement["lineHeight"],
): CartesianAxisLabelSpec => {
const minWidth = Math.max(
CARTESIAN_LABEL_MIN_WIDTH,
Math.ceil(getApproxMinLineWidth(fontString, lineHeight)),
);
const maxWidth = Math.max(minWidth, Math.floor(maxLabelWidth));
const candidateWidths: number[] = [];
for (let width = maxWidth; width >= minWidth; width -= 4) {
candidateWidths.push(width);
}
if (candidateWidths[candidateWidths.length - 1] !== minWidth) {
candidateWidths.push(minWidth);
}
const getRank = (spec: CartesianAxisLabelSpec) => {
const ellipsified = isEllipsifiedLabel(spec.text);
const visibleChars = spec.text
.replace(/\.\.\./g, "")
.replace(/\n/g, "").length;
const lineCount = spec.text.split("\n").length;
return {
ellipsified,
visibleChars,
lineCount,
};
};
const shouldPrefer = (
candidate: CartesianAxisLabelSpec,
current: CartesianAxisLabelSpec,
) => {
const candidateRank = getRank(candidate);
const currentRank = getRank(current);
if (candidateRank.ellipsified !== currentRank.ellipsified) {
return !candidateRank.ellipsified;
}
if (candidateRank.visibleChars !== currentRank.visibleChars) {
return candidateRank.visibleChars > currentRank.visibleChars;
}
if (candidateRank.lineCount !== currentRank.lineCount) {
return candidateRank.lineCount < currentRank.lineCount;
}
return candidate.rotatedHeight < current.rotatedHeight;
};
let bestFit: CartesianAxisLabelSpec | null = null;
let bestOverflowAny: {
overflow: number;
spec: CartesianAxisLabelSpec;
} | null = null;
let bestOverflowNonEllipsified: {
overflow: number;
spec: CartesianAxisLabelSpec;
} | null = null;
for (const width of candidateWidths) {
const { wrapped, text } = wrapOrEllipsifyTextToWidth(
label,
width,
fontString,
lineHeight,
);
const metrics = measureText(text, fontString, lineHeight);
const rotated = getRotatedBoundingBox(
metrics.width,
metrics.height,
CARTESIAN_LABEL_ROTATION,
);
const spec = {
originalText: label,
text,
metrics,
rotatedWidth: rotated.width,
rotatedHeight: rotated.height,
wrapped,
};
const overflow = rotated.width - maxRotatedWidth;
if (overflow <= 0) {
if (!bestFit || shouldPrefer(spec, bestFit)) {
bestFit = spec;
}
continue;
}
if (
!bestOverflowAny ||
overflow < bestOverflowAny.overflow ||
(overflow === bestOverflowAny.overflow &&
shouldPrefer(spec, bestOverflowAny.spec))
) {
bestOverflowAny = { overflow, spec };
}
if (
!isEllipsifiedLabel(spec.text) &&
(!bestOverflowNonEllipsified ||
overflow < bestOverflowNonEllipsified.overflow ||
(overflow === bestOverflowNonEllipsified.overflow &&
shouldPrefer(spec, bestOverflowNonEllipsified.spec)))
) {
bestOverflowNonEllipsified = { overflow, spec };
}
}
if (bestFit) {
return bestFit;
}
if (
bestOverflowNonEllipsified &&
bestOverflowAny &&
bestOverflowNonEllipsified.overflow <=
bestOverflowAny.overflow + CARTESIAN_LABEL_OVERFLOW_PREFERENCE_BUFFER
) {
return bestOverflowNonEllipsified.spec;
}
return bestOverflowAny!.spec;
};
export const getRotatedTextElementBottom = (
element: NonDeletedExcalidrawElement,
) => {
if (element.type !== "text") {
return element.y + element.height;
}
const rotated = getRotatedBoundingBox(
element.width,
element.height,
element.angle,
);
return element.y + element.height / 2 + rotated.height / 2;
};
export const chartXLabels = (
spreadsheet: Spreadsheet,
x: number,
y: number,
backgroundColor: string,
layout: CartesianChartLayout,
): ChartElements => {
const fontFamily = commonProps.fontFamily;
const fontSize = FONT_SIZES.sm;
const lineHeight = getLineHeight(fontFamily);
const fontString = getFontString({ fontFamily, fontSize });
const maxRotatedWidth = Math.max(
1,
layout.slotWidth +
layout.gap -
CARTESIAN_LABEL_SLOT_PADDING * 2 +
CARTESIAN_LABEL_ROTATED_WIDTH_BUFFER,
);
const axisY = y;
return (
spreadsheet.labels?.map((label, index) => {
const labelSpec = getCartesianAxisLabelSpec(
label,
layout.xLabelMaxWidth,
maxRotatedWidth,
fontString,
lineHeight,
);
const centerX =
x +
index * (layout.slotWidth + layout.gap) +
layout.gap +
layout.slotWidth / 2;
const labelY =
axisY +
CARTESIAN_LABEL_AXIS_CLEARANCE +
(labelSpec.rotatedHeight - labelSpec.metrics.height) / 2;
return newTextElement({
backgroundColor,
...commonProps,
text: labelSpec.text,
originalText: labelSpec.wrapped ? label : labelSpec.text,
autoResize: !labelSpec.wrapped,
x: centerX,
y: labelY,
angle: CARTESIAN_LABEL_ROTATION,
fontSize,
lineHeight,
textAlign: "center",
verticalAlign: "top",
});
}) || []
);
};
const chartYLabels = (
spreadsheet: Spreadsheet,
x: number,
y: number,
backgroundColor: string,
layout: CartesianChartLayout,
maxValue = Math.max(...spreadsheet.series[0].values),
): ChartElements => {
const minYLabel = newTextElement({
backgroundColor,
...commonProps,
x: x - layout.gap,
y: y - layout.gap,
text: "0",
textAlign: "right",
});
const maxYLabel = newTextElement({
backgroundColor,
...commonProps,
x: x - layout.gap,
y: y - layout.chartHeight - minYLabel.height / 2,
text: maxValue.toLocaleString(),
textAlign: "right",
});
return [minYLabel, maxYLabel];
};
const chartLines = (
spreadsheet: Spreadsheet,
x: number,
y: number,
backgroundColor: string,
layout: CartesianChartLayout,
): ChartElements => {
const { chartWidth, chartHeight } = getChartDimensions(spreadsheet, layout);
const xLine = newLinearElement({
backgroundColor,
...commonProps,
type: "line",
x,
y,
width: chartWidth,
points: [pointFrom(0, 0), pointFrom(chartWidth, 0)],
});
const yLine = newLinearElement({
backgroundColor,
...commonProps,
type: "line",
x,
y,
height: chartHeight,
points: [pointFrom(0, 0), pointFrom(0, -chartHeight)],
});
const maxLine = newLinearElement({
backgroundColor,
...commonProps,
type: "line",
x,
y: y - layout.chartHeight - layout.gap,
strokeStyle: "dotted",
width: chartWidth,
opacity: GRID_OPACITY,
points: [pointFrom(0, 0), pointFrom(chartWidth, 0)],
});
return [xLine, yLine, maxLine];
};
// For the maths behind it https://excalidraw.com/#json=6320864370884608,O_5xfD-Agh32tytHpRJx1g
export const chartBaseElements = (
spreadsheet: Spreadsheet,
x: number,
y: number,
backgroundColor: string,
layout: CartesianChartLayout,
maxValue = Math.max(...spreadsheet.series[0].values),
debug?: boolean,
): ChartElements => {
const { chartWidth, chartHeight } = getChartDimensions(spreadsheet, layout);
const title = spreadsheet.title
? newTextElement({
backgroundColor,
...commonProps,
text: spreadsheet.title,
x: x + chartWidth / 2,
y: y - layout.chartHeight - layout.gap * 2 - DEFAULT_FONT_SIZE,
roundness: null,
textAlign: "center",
fontSize: FONT_SIZES.xl,
fontFamily: FONT_FAMILY["Lilita One"],
})
: null;
const debugRect = debug
? newElement({
backgroundColor,
...commonProps,
type: "rectangle",
x,
y: y - chartHeight,
width: chartWidth,
height: chartHeight,
strokeColor: COLOR_PALETTE.black,
fillStyle: "solid",
opacity: 6,
})
: null;
return [
...(debugRect ? [debugRect] : []),
...(title ? [title] : []),
...chartXLabels(spreadsheet, x, y, backgroundColor, layout),
...chartYLabels(spreadsheet, x, y, backgroundColor, layout, maxValue),
...chartLines(spreadsheet, x, y, backgroundColor, layout),
];
};
-130
View File
@@ -1,130 +0,0 @@
import { pointFrom } from "@excalidraw/math";
import { isDevEnv } from "@excalidraw/common";
import { newElement, newLinearElement } from "@excalidraw/element";
import type { LocalPoint } from "@excalidraw/math";
import { GRID_OPACITY, commonProps } from "./charts.constants";
import {
chartBaseElements,
chartXLabels,
createSeriesLegend,
getBackgroundColor,
getCartesianChartLayout,
getChartDimensions,
getColorOffset,
getRotatedTextElementBottom,
getSeriesColors,
} from "./charts.helpers";
import type { ChartElements, Spreadsheet } from "./charts.types";
export const renderLineChart = (
spreadsheet: Spreadsheet,
x: number,
y: number,
colorSeed?: number,
): ChartElements => {
const series = spreadsheet.series;
const layout = getCartesianChartLayout("line", series.length);
const max = Math.max(1, ...series.flatMap((seriesData) => seriesData.values));
const colorOffset = getColorOffset(colorSeed);
const backgroundColor = getBackgroundColor(colorOffset);
const seriesColors = getSeriesColors(series.length, colorOffset);
const lines = series.map((seriesData, seriesIndex) => {
const points = seriesData.values.map((value, valueIndex) =>
pointFrom<LocalPoint>(
valueIndex * (layout.slotWidth + layout.gap),
-(value / max) * layout.chartHeight,
),
);
const maxX = Math.max(...points.map((point) => point[0]));
const maxY = Math.max(...points.map((point) => point[1]));
const minX = Math.min(...points.map((point) => point[0]));
const minY = Math.min(...points.map((point) => point[1]));
return newLinearElement({
backgroundColor: "transparent",
...commonProps,
type: "line",
x: x + layout.gap + layout.slotWidth / 2,
y: y - layout.gap,
height: maxY - minY,
width: maxX - minX,
strokeColor: seriesColors[seriesIndex],
strokeWidth: 2,
points,
});
});
const dots = series.flatMap((seriesData, seriesIndex) =>
seriesData.values.map((value, valueIndex) => {
const cx = valueIndex * (layout.slotWidth + layout.gap) + layout.gap / 2;
const cy = -(value / max) * layout.chartHeight + layout.gap / 2;
return newElement({
backgroundColor: seriesColors[seriesIndex],
...commonProps,
fillStyle: "solid",
strokeColor: seriesColors[seriesIndex],
strokeWidth: 2,
type: "ellipse",
x: x + cx + layout.slotWidth / 2,
y: y + cy - layout.gap * 2,
width: layout.gap,
height: layout.gap,
});
}),
);
const guideValues = series[0].values.map((_, valueIndex) =>
Math.max(
0,
...series.map((seriesData) => seriesData.values[valueIndex] ?? 0),
),
);
const guides = guideValues.map((value, valueIndex) => {
const cx = valueIndex * (layout.slotWidth + layout.gap) + layout.gap / 2;
const cy = (value / max) * layout.chartHeight + layout.gap / 2 + layout.gap;
return newLinearElement({
backgroundColor,
...commonProps,
type: "line",
x: x + cx + layout.slotWidth / 2 + layout.gap / 2,
y: y - cy,
height: cy,
strokeStyle: "dotted",
opacity: GRID_OPACITY,
points: [pointFrom(0, 0), pointFrom(0, cy)],
});
});
const baseElements = chartBaseElements(
spreadsheet,
x,
y,
backgroundColor,
layout,
max,
isDevEnv(),
);
const xLabels = chartXLabels(spreadsheet, x, y, backgroundColor, layout);
const xLabelsBottomY = Math.max(
y + layout.gap / 2,
...xLabels.map((label) => getRotatedTextElementBottom(label)),
);
const { chartWidth } = getChartDimensions(spreadsheet, layout);
const seriesLegend = createSeriesLegend(
series,
seriesColors,
x + chartWidth / 2,
xLabelsBottomY,
y + layout.gap * 5,
backgroundColor,
);
return [...baseElements, ...lines, ...guides, ...dots, ...seriesLegend];
};
-174
View File
@@ -1,174 +0,0 @@
import { type ParseSpreadsheetResult } from "./charts.types";
/**
* @private exported for testing
*/
export const tryParseNumber = (s: string): number | null => {
const match =
/^([-+]?)[$\u20AC\u00A3\u00A5\u20A9]?([-+]?)([\d.,]+)[%]?$/.exec(s);
if (!match) {
return null;
}
return parseFloat(`${(match[1] || match[2]) + match[3]}`.replace(/,/g, ""));
};
const isNumericColumn = (lines: string[][], columnIndex: number) =>
lines.slice(1).every((line) => tryParseNumber(line[columnIndex]) !== null);
/**
* @private exported for testing
*/
export const tryParseCells = (cells: string[][]): ParseSpreadsheetResult => {
const numCols = cells[0].length;
if (numCols > 2) {
const hasHeader = cells[0].every((cell) => tryParseNumber(cell) === null);
const rows = hasHeader ? cells.slice(1) : cells;
if (rows.length < 1) {
return { ok: false, reason: "No data rows" };
}
const invalidNumericColumn = rows.some((row) =>
row.slice(1).some((value) => tryParseNumber(value) === null),
);
if (invalidNumericColumn) {
return { ok: false, reason: "Value is not numeric" };
}
// When there are more value columns than data rows, the data is in
// "wide" format — transpose so columns become labels (dimensions)
// and rows become series. This enables e.g. radar charts for wide data.
const numValueCols = numCols - 1;
if (numValueCols > rows.length) {
const labels = hasHeader ? cells[0].slice(1).map((h) => h.trim()) : null;
const series = rows.map((row) => ({
title: row[0]?.trim() || null,
values: row.slice(1).map((v) => tryParseNumber(v)!),
}));
const title =
series.length === 1
? series[0].title
: hasHeader
? cells[0][0].trim() || null
: null;
return {
ok: true,
data: { title, labels, series },
};
}
const series = cells[0].slice(1).map((seriesTitle, index) => {
const valueColumnIndex = index + 1;
const fallbackTitle = `Series ${valueColumnIndex}`;
return {
title: hasHeader ? seriesTitle.trim() || fallbackTitle : fallbackTitle,
values: rows.map((row) => tryParseNumber(row[valueColumnIndex])!),
};
});
return {
ok: true,
data: {
title: hasHeader ? cells[0][0].trim() || null : null,
labels: rows.map((row) => row[0]),
series,
},
};
}
if (numCols === 1) {
if (!isNumericColumn(cells, 0)) {
return { ok: false, reason: "Value is not numeric" };
}
const hasHeader = tryParseNumber(cells[0][0]) === null;
const title = hasHeader ? cells[0][0] : null;
const values = (hasHeader ? cells.slice(1) : cells).map((line) =>
tryParseNumber(line[0]),
);
if (values.length < 2) {
return { ok: false, reason: "Less than two rows" };
}
return {
ok: true,
data: {
title,
labels: null,
series: [{ title, values: values as number[] }],
},
};
}
const hasHeader = tryParseNumber(cells[0][1]) === null;
const rows = hasHeader ? cells.slice(1) : cells;
if (rows.length < 2) {
return { ok: false, reason: "Less than 2 rows" };
}
const invalidNumericColumn = rows.some(
(row) => tryParseNumber(row[1]) === null,
);
if (invalidNumericColumn) {
return { ok: false, reason: "Value is not numeric" };
}
const title = hasHeader ? cells[0][1] : null;
return {
ok: true,
data: {
title,
labels: rows.map((row) => row[0]),
series: [{ title, values: rows.map((row) => tryParseNumber(row[1])!) }],
},
};
};
export const tryParseSpreadsheet = (text: string): ParseSpreadsheetResult => {
// Copy/paste from excel, spreadsheets, TSV, CSV, semicolon-separated.
const parseDelimitedLines = (delimiter: "\t" | "," | ";") =>
text
.replace(/\r\n?/g, "\n")
.split("\n")
.filter((line) => line.trim().length > 0)
.map((line) => line.split(delimiter).map((cell) => cell.trim()));
// Score each delimiter: prefer consistent column counts with the most columns.
// A delimiter that produces all single-column rows likely isn't the right one.
const candidates = (["\t", ",", ";"] as const).map((delimiter) => {
const parsed = parseDelimitedLines(delimiter);
const numCols = parsed[0]?.length ?? 0;
const isConsistent =
parsed.length > 0 && parsed.every((line) => line.length === numCols);
return { delimiter, parsed, numCols, isConsistent };
});
// Prefer: consistent + most columns. Among ties, tab > comma > semicolon
// (the array order already encodes this priority).
const best =
candidates.find((c) => c.isConsistent && c.numCols > 1) ??
candidates.find((c) => c.isConsistent) ??
candidates[0];
const lines = best.parsed;
if (lines.length === 0) {
return { ok: false, reason: "No values" };
}
const numColsFirstLine = lines[0].length;
const isSpreadsheet = lines.every((line) => line.length === numColsFirstLine);
if (!isSpreadsheet) {
return {
ok: false,
reason: "All rows don't have same number of columns",
};
}
return tryParseCells(lines);
};
-199
View File
@@ -1,199 +0,0 @@
import { pointFrom } from "@excalidraw/math";
import {
FONT_FAMILY,
FONT_SIZES,
getFontString,
getLineHeight,
ROUGHNESS,
} from "@excalidraw/common";
import {
measureText,
newLinearElement,
newTextElement,
} from "@excalidraw/element";
import type { LocalPoint } from "@excalidraw/math";
import {
BAR_GAP,
BAR_HEIGHT,
GRID_OPACITY,
RADAR_GRID_LEVELS,
RADAR_LABEL_OFFSET,
commonProps,
} from "./charts.constants";
import {
createRadarAxisLabels,
createSeriesLegend,
getBackgroundColor,
getColorOffset,
getRadarDimensions,
getRadarDisplayText,
getRadarValueScale,
getSeriesColors,
isSpreadsheetValidForChartType,
} from "./charts.helpers";
import type { ChartElements, Spreadsheet } from "./charts.types";
export const renderRadarChart = (
spreadsheet: Spreadsheet,
x: number,
y: number,
colorSeed?: number,
): ChartElements | null => {
if (!isSpreadsheetValidForChartType(spreadsheet, "radar")) {
return null;
}
const labels =
spreadsheet.labels ??
spreadsheet.series[0].values.map((_, index) => `Value ${index + 1}`);
const series = spreadsheet.series;
const { normalize, renderSteps } = getRadarValueScale(series, labels.length);
const colorOffset = getColorOffset(colorSeed);
const backgroundColor = getBackgroundColor(colorOffset);
const seriesColors = getSeriesColors(series.length, colorOffset);
const { chartWidth, chartHeight } = getRadarDimensions();
const centerX = x + chartWidth / 2;
const centerY = y - chartHeight / 2;
const radius = BAR_HEIGHT / 2;
const angles = labels.map(
(_, index) => -Math.PI / 2 + (Math.PI * 2 * index) / labels.length,
);
const { axisLabels, axisLabelTopY, axisLabelBottomY } = createRadarAxisLabels(
labels,
angles,
centerX,
centerY,
radius,
backgroundColor,
);
const titleFontFamily = FONT_FAMILY["Lilita One"];
const titleFontSize = FONT_SIZES.xl;
const titleLineHeight = getLineHeight(titleFontFamily);
const titleFontString = getFontString({
fontFamily: titleFontFamily,
fontSize: titleFontSize,
});
const titleText = spreadsheet.title
? getRadarDisplayText(
spreadsheet.title,
titleFontString,
chartWidth + RADAR_LABEL_OFFSET * 2,
)
: null;
const titleTextMetrics = titleText
? measureText(titleText, titleFontString, titleLineHeight)
: null;
const title = titleText
? newTextElement({
backgroundColor,
...commonProps,
text: titleText,
originalText: spreadsheet.title ?? titleText,
x: x + chartWidth / 2,
y: axisLabelTopY - RADAR_LABEL_OFFSET - titleTextMetrics!.height / 2,
fontFamily: titleFontFamily,
fontSize: titleFontSize,
lineHeight: titleLineHeight,
textAlign: "center",
})
: null;
const radarGridLines = renderSteps
? Array.from({ length: RADAR_GRID_LEVELS }, (_, levelIndex) => {
const levelRatio = (levelIndex + 1) / RADAR_GRID_LEVELS;
const levelRadius = radius * levelRatio;
const points = angles.map((angle) =>
pointFrom<LocalPoint>(
Math.cos(angle) * levelRadius,
Math.sin(angle) * levelRadius,
),
);
points.push(pointFrom(points[0][0], points[0][1]));
return newLinearElement({
backgroundColor: "transparent",
...commonProps,
type: "line",
x: centerX,
y: centerY,
width: levelRadius * 2,
height: levelRadius * 2,
strokeStyle: "solid",
roughness: ROUGHNESS.architect,
opacity: GRID_OPACITY,
polygon: true,
points,
});
})
: [];
const spokes = angles.map((angle) => {
const px = Math.cos(angle) * radius;
const py = Math.sin(angle) * radius;
return newLinearElement({
backgroundColor: "transparent",
...commonProps,
type: "line",
x: centerX,
y: centerY,
width: Math.abs(px),
height: Math.abs(py),
strokeStyle: "solid",
roughness: ROUGHNESS.architect,
opacity: GRID_OPACITY,
points: [pointFrom(0, 0), pointFrom(px, py)],
});
});
const seriesPolygons = series.map((seriesData, index) => {
const points = angles.map((angle, axisIndex) => {
const value = seriesData.values[axisIndex] ?? 0;
const pointRadius = normalize(value, axisIndex) * radius;
return pointFrom<LocalPoint>(
Math.cos(angle) * pointRadius,
Math.sin(angle) * pointRadius,
);
});
points.push(pointFrom(points[0][0], points[0][1]));
return newLinearElement({
backgroundColor: "transparent",
...commonProps,
type: "line",
x: centerX,
y: centerY,
width: radius * 2,
height: radius * 2,
strokeColor: seriesColors[index],
strokeWidth: 2,
polygon: true,
points,
});
});
const seriesLegend = createSeriesLegend(
series,
seriesColors,
centerX,
axisLabelBottomY,
y + BAR_GAP * 5,
backgroundColor,
);
return [
...(title ? [title] : []),
...axisLabels,
...radarGridLines,
...spokes,
...seriesPolygons,
...seriesLegend,
];
};
@@ -1,18 +0,0 @@
import type { NonDeletedExcalidrawElement } from "@excalidraw/element/types";
export type ChartElements = readonly NonDeletedExcalidrawElement[];
export interface Spreadsheet {
title: string | null;
labels: string[] | null;
series: SpreadsheetSeries[];
}
export interface SpreadsheetSeries {
title: string | null;
values: number[];
}
export type ParseSpreadsheetResult =
| { ok: false; reason: string }
| { ok: true; data: Spreadsheet };
-38
View File
@@ -1,38 +0,0 @@
import type { ChartType } from "@excalidraw/element/types";
import { renderBarChart } from "./charts.bar";
import { renderLineChart } from "./charts.line";
import {
tryParseCells,
tryParseNumber,
tryParseSpreadsheet,
} from "./charts.parse";
import { renderRadarChart } from "./charts.radar";
import type { ChartElements, Spreadsheet } from "./charts.types";
export {
type ParseSpreadsheetResult,
type Spreadsheet,
type SpreadsheetSeries,
type ChartElements,
} from "./charts.types";
export { isSpreadsheetValidForChartType } from "./charts.helpers";
export { tryParseCells, tryParseNumber, tryParseSpreadsheet };
export const renderSpreadsheet = (
chartType: ChartType,
spreadsheet: Spreadsheet,
x: number,
y: number,
colorSeed?: number,
): ChartElements | null => {
if (chartType === "line") {
return renderLineChart(spreadsheet, x, y, colorSeed);
}
if (chartType === "radar") {
return renderRadarChart(spreadsheet, x, y, colorSeed);
}
return renderBarChart(spreadsheet, x, y, colorSeed);
};
+63
View File
@@ -155,4 +155,67 @@ describe("parseClipboard()", () => {
}, },
]); ]);
}); });
it("should parse spreadsheet from either text/plain and text/html", async () => {
let clipboardData;
// -------------------------------------------------------------------------
clipboardData = await parseClipboard(
await parseDataTransferEvent(
createPasteEvent({
types: {
"text/plain": `a b
1 2
4 5
7 10`,
},
}),
),
);
expect(clipboardData.spreadsheet).toEqual({
title: "b",
labels: ["1", "4", "7"],
values: [2, 5, 10],
});
// -------------------------------------------------------------------------
clipboardData = await parseClipboard(
await parseDataTransferEvent(
createPasteEvent({
types: {
"text/html": `a b
1 2
4 5
7 10`,
},
}),
),
);
expect(clipboardData.spreadsheet).toEqual({
title: "b",
labels: ["1", "4", "7"],
values: [2, 5, 10],
});
// -------------------------------------------------------------------------
clipboardData = await parseClipboard(
await parseDataTransferEvent(
createPasteEvent({
types: {
"text/html": `<html>
<body>
<!--StartFragment--><google-sheets-html-origin><style type="text/css"><!--td {border: 1px solid #cccccc;}br {mso-data-placement:same-cell;}--></style><table xmlns="http://www.w3.org/1999/xhtml" cellspacing="0" cellpadding="0" dir="ltr" border="1" style="table-layout:fixed;font-size:10pt;font-family:Arial;width:0px;border-collapse:collapse;border:none"><colgroup><col width="100"/><col width="100"/></colgroup><tbody><tr style="height:21px;"><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;a&quot;}">a</td><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;b&quot;}">b</td></tr><tr style="height:21px;"><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;text-align:right;" data-sheets-value="{&quot;1&quot;:3,&quot;3&quot;:1}">1</td><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;text-align:right;" data-sheets-value="{&quot;1&quot;:3,&quot;3&quot;:2}">2</td></tr><tr style="height:21px;"><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;text-align:right;" data-sheets-value="{&quot;1&quot;:3,&quot;3&quot;:4}">4</td><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;text-align:right;" data-sheets-value="{&quot;1&quot;:3,&quot;3&quot;:5}">5</td></tr><tr style="height:21px;"><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;text-align:right;" data-sheets-value="{&quot;1&quot;:3,&quot;3&quot;:7}">7</td><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;text-align:right;" data-sheets-value="{&quot;1&quot;:3,&quot;3&quot;:10}">10</td></tr></tbody></table><!--EndFragment-->
</body>
</html>`,
"text/plain": `a b
1 2
4 5
7 10`,
},
}),
),
);
expect(clipboardData.spreadsheet).toEqual({
title: "b",
labels: ["1", "4", "7"],
values: [2, 5, 10],
});
});
}); });
+28
View File
@@ -33,8 +33,12 @@ import {
normalizeFile, normalizeFile,
} from "./data/blob"; } from "./data/blob";
import { tryParseSpreadsheet, VALID_SPREADSHEET } from "./charts";
import type { FileSystemHandle } from "./data/filesystem"; import type { FileSystemHandle } from "./data/filesystem";
import type { Spreadsheet } from "./charts";
import type { BinaryFiles } from "./types"; import type { BinaryFiles } from "./types";
type ElementsClipboard = { type ElementsClipboard = {
@@ -46,6 +50,7 @@ type ElementsClipboard = {
export type PastedMixedContent = { type: "text" | "imageUrl"; value: string }[]; export type PastedMixedContent = { type: "text" | "imageUrl"; value: string }[];
export interface ClipboardData { export interface ClipboardData {
spreadsheet?: Spreadsheet;
elements?: readonly ExcalidrawElement[]; elements?: readonly ExcalidrawElement[];
files?: BinaryFiles; files?: BinaryFiles;
text?: string; text?: string;
@@ -210,6 +215,16 @@ export const copyToClipboard = async (
); );
}; };
const parsePotentialSpreadsheet = (
text: string,
): { spreadsheet: Spreadsheet } | { errorMessage: string } | null => {
const result = tryParseSpreadsheet(text);
if (result.type === VALID_SPREADSHEET) {
return { spreadsheet: result.spreadsheet };
}
return null;
};
/** internal, specific to parsing paste events. Do not reuse. */ /** internal, specific to parsing paste events. Do not reuse. */
function parseHTMLTree(el: ChildNode) { function parseHTMLTree(el: ChildNode) {
let result: PastedMixedContent = []; let result: PastedMixedContent = [];
@@ -536,6 +551,19 @@ export const parseClipboard = async (
}; };
} }
try {
// if system clipboard contains spreadsheet, use it even though it's
// technically possible it's staler than in-app clipboard
const spreadsheetResult =
!isPlainPaste && parsePotentialSpreadsheet(parsedEventData.value);
if (spreadsheetResult) {
return spreadsheetResult;
}
} catch (error: any) {
console.error(error);
}
try { try {
const systemClipboardData = JSON.parse(parsedEventData.value); const systemClipboardData = JSON.parse(parsedEventData.value);
const programmaticAPI = const programmaticAPI =
+3 -7
View File
@@ -226,7 +226,7 @@ export const SelectedShapeActions = ({
{(appState.activeTool.type === "text" || {(appState.activeTool.type === "text" ||
targetElements.some(isTextElement)) && ( targetElements.some(isTextElement)) && (
<> <>
<fieldset>{renderAction("changeFontFamily")}</fieldset> {renderAction("changeFontFamily")}
{renderAction("changeFontSize")} {renderAction("changeFontSize")}
{(appState.activeTool.type === "text" || {(appState.activeTool.type === "text" ||
suppportsHorizontalAlign(targetElements, elementsMap)) && suppportsHorizontalAlign(targetElements, elementsMap)) &&
@@ -1081,9 +1081,8 @@ export const ShapesSwitcher = ({
return ( return (
<> <>
{getToolbarTools(app).map( {getToolbarTools(app).map(
({ value, icon, key, numericKey, fillable, toolbar }) => { ({ value, icon, key, numericKey, fillable }, index) => {
if ( if (
toolbar === false ||
UIOptions.tools?.[ UIOptions.tools?.[
value as Extract< value as Extract<
typeof value, typeof value,
@@ -1100,9 +1099,6 @@ export const ShapesSwitcher = ({
const shortcut = letter const shortcut = letter
? `${letter} ${t("helpDialog.or")} ${numericKey}` ? `${letter} ${t("helpDialog.or")} ${numericKey}`
: `${numericKey}`; : `${numericKey}`;
const keybindingLabel =
value === "hand" ? undefined : numericKey || letter;
// when in compact styles panel mode (tablet) // when in compact styles panel mode (tablet)
// use a ToolPopover for selection/lasso toggle as well // use a ToolPopover for selection/lasso toggle as well
if ( if (
@@ -1147,7 +1143,7 @@ export const ShapesSwitcher = ({
checked={activeTool.type === value} checked={activeTool.type === value}
name="editor-current-shape" name="editor-current-shape"
title={`${capitalizeString(label)}${shortcut}`} title={`${capitalizeString(label)}${shortcut}`}
keyBindingLabel={keybindingLabel} keyBindingLabel={numericKey || letter}
aria-label={capitalizeString(label)} aria-label={capitalizeString(label)}
aria-keyshortcuts={shortcut} aria-keyshortcuts={shortcut}
data-testid={`toolbar-${value}`} data-testid={`toolbar-${value}`}
+155 -221
View File
@@ -108,7 +108,6 @@ import {
loadDesktopUIModePreference, loadDesktopUIModePreference,
setDesktopUIMode, setDesktopUIMode,
isSelectionLikeTool, isSelectionLikeTool,
oneOf,
} from "@excalidraw/common"; } from "@excalidraw/common";
import { import {
@@ -119,6 +118,7 @@ import {
fixBindingsAfterDeletion, fixBindingsAfterDeletion,
getHoveredElementForBinding, getHoveredElementForBinding,
isBindingEnabled, isBindingEnabled,
shouldEnableBindingForPointerEvent,
updateBoundElements, updateBoundElements,
LinearElementEditor, LinearElementEditor,
newElementWith, newElementWith,
@@ -318,8 +318,6 @@ import {
actionToggleElementLock, actionToggleElementLock,
actionToggleLinearEditor, actionToggleLinearEditor,
actionToggleObjectsSnapMode, actionToggleObjectsSnapMode,
actionToggleArrowBinding,
actionToggleMidpointSnapping,
actionToggleCropEditor, actionToggleCropEditor,
} from "../actions"; } from "../actions";
import { actionWrapTextInContainer } from "../actions/actionBoundText"; import { actionWrapTextInContainer } from "../actions/actionBoundText";
@@ -426,8 +424,6 @@ import { EraserTrail } from "../eraser";
import { getShortcutKey } from "../shortcut"; import { getShortcutKey } from "../shortcut";
import { tryParseSpreadsheet } from "../charts";
import ConvertElementTypePopup, { import ConvertElementTypePopup, {
getConversionTypeFromElements, getConversionTypeFromElements,
convertElementTypePopupAtom, convertElementTypePopupAtom,
@@ -1223,14 +1219,12 @@ class App extends React.Component<AppProps, AppState> {
if ( if (
hitElement && hitElement &&
isIframeLikeElement(hitElement) && isIframeLikeElement(hitElement) &&
(this.state.viewModeEnabled || this.isIframeLikeElementCenter(
this.state.activeTool.type === "laser" || hitElement,
this.isIframeLikeElementCenter( moveEvent,
hitElement, scenePointer.x,
moveEvent, scenePointer.y,
scenePointer.x, )
scenePointer.y,
))
) { ) {
setCursor(this.interactiveCanvas, CURSOR_TYPE.POINTER); setCursor(this.interactiveCanvas, CURSOR_TYPE.POINTER);
this.setState({ this.setState({
@@ -1245,72 +1239,61 @@ class App extends React.Component<AppProps, AppState> {
/** @returns true if iframe-like element click handled */ /** @returns true if iframe-like element click handled */
private handleIframeLikeCenterClick(): boolean { private handleIframeLikeCenterClick(): boolean {
if (!this.lastPointerDownEvent || !this.lastPointerUpEvent) {
return false;
}
const scenePointerStart = viewportCoordsToSceneCoords(
{
clientX: this.lastPointerDownEvent.clientX,
clientY: this.lastPointerDownEvent.clientY,
},
this.state,
);
const scenePointerEnd = viewportCoordsToSceneCoords(
{
clientX: this.lastPointerUpEvent.clientX,
clientY: this.lastPointerUpEvent.clientY,
},
this.state,
);
const hitElementStart = this.getElementAtPosition(
scenePointerStart.x,
scenePointerStart.y,
);
const hitElementEnd = this.getElementAtPosition(
scenePointerEnd.x,
scenePointerEnd.y,
);
if ( if (
!this.lastPointerDownEvent || !hitElementStart ||
!this.lastPointerUpEvent || !hitElementEnd ||
// middle-click or something other than primary hitElementStart !== hitElementEnd ||
this.lastPointerDownEvent.button !== POINTER_BUTTON.MAIN || this.lastPointerUpEvent.timeStamp - this.lastPointerDownEvent.timeStamp >
// panning 300 ||
isHoldingSpace || gesture.pointers.size > 1 ||
// wrong tool !isIframeLikeElement(hitElementStart) ||
!oneOf(this.state.activeTool.type, ["laser", "selection", "lasso"]) !isIframeLikeElement(hitElementEnd) ||
!this.isIframeLikeElementCenter(
hitElementStart,
this.lastPointerUpEvent,
scenePointerStart.x,
scenePointerStart.y,
) ||
!this.isIframeLikeElementCenter(
hitElementEnd,
this.lastPointerUpEvent,
scenePointerEnd.x,
scenePointerEnd.y,
)
) { ) {
return false; return false;
} }
const viewportClickStart_scenePoint = pointFrom( const iframeLikeElement = hitElementEnd;
viewportCoordsToSceneCoords(
{
clientX: this.lastPointerDownEvent.clientX,
clientY: this.lastPointerDownEvent.clientY,
},
this.state,
),
);
const viewportClickEnd_scenePoint = pointFrom(
viewportCoordsToSceneCoords(
{
clientX: this.lastPointerUpEvent.clientX,
clientY: this.lastPointerUpEvent.clientY,
},
this.state,
),
);
const draggedDistance = pointDistance(
viewportClickStart_scenePoint,
viewportClickEnd_scenePoint,
);
if (draggedDistance > DRAGGING_THRESHOLD) {
return false;
}
const hitElement = this.getElementAtPosition(
viewportClickStart_scenePoint[0],
viewportClickStart_scenePoint[1],
);
const shouldActivate =
hitElement &&
this.lastPointerUpEvent.timeStamp - this.lastPointerDownEvent.timeStamp <=
300 &&
gesture.pointers.size < 2 &&
isIframeLikeElement(hitElement) &&
(this.state.viewModeEnabled ||
this.state.activeTool.type === "laser" ||
this.isIframeLikeElementCenter(
hitElement,
this.lastPointerUpEvent,
viewportClickEnd_scenePoint[0],
viewportClickEnd_scenePoint[1],
));
if (!shouldActivate) {
return false;
}
const iframeLikeElement = hitElement;
if ( if (
this.state.activeEmbeddable?.element === iframeLikeElement && this.state.activeEmbeddable?.element === iframeLikeElement &&
@@ -2735,9 +2718,7 @@ class App extends React.Component<AppProps, AppState> {
private onBlur = withBatchedUpdates(() => { private onBlur = withBatchedUpdates(() => {
isHoldingSpace = false; isHoldingSpace = false;
this.setState({ this.setState({ isBindingEnabled: true });
isBindingEnabled: this.state.bindingPreference === "enabled",
});
}); });
private onUnload = () => { private onUnload = () => {
@@ -3547,19 +3528,14 @@ class App extends React.Component<AppProps, AppState> {
} }
// ------------------- Spreadsheet ------------------- // ------------------- Spreadsheet -------------------
if (data.spreadsheet && !isPlainPaste) {
if (!isPlainPaste && data.text) { this.setState({
const result = tryParseSpreadsheet(data.text); pasteDialog: {
if (result.ok) { data: data.spreadsheet,
this.setState({ shown: true,
openDialog: { },
name: "charts", });
data: result.data, return;
rawText: data.text,
},
});
return;
}
} }
// ------------------- Images or SVG code ------------------- // ------------------- Images or SVG code -------------------
@@ -4868,87 +4844,17 @@ class App extends React.Component<AppProps, AppState> {
return; return;
} }
// view mode hardcoded from upstream -> disable tool switching for now
const shouldPreventToolSwitching = this.props.viewModeEnabled === true;
if (
!shouldPreventToolSwitching &&
this.state.viewModeEnabled &&
event.key === KEYS.ESCAPE
) {
this.setActiveTool({ type: "selection" });
return;
}
if (
!shouldPreventToolSwitching &&
!event.ctrlKey &&
!event.altKey &&
!event.metaKey &&
!this.state.newElement &&
!this.state.selectionElement &&
!this.state.selectedElementsAreBeingDragged
) {
const shape = findShapeByKey(event.key, this);
if (this.state.viewModeEnabled && !oneOf(shape, ["laser", "hand"])) {
return;
}
if (shape) {
if (this.state.activeTool.type !== shape) {
trackEvent(
"toolbar",
shape,
`keyboard (${
this.editorInterface.formFactor === "phone"
? "mobile"
: "desktop"
})`,
);
}
if (shape === "arrow" && this.state.activeTool.type === "arrow") {
this.setState((prevState) => ({
currentItemArrowType:
prevState.currentItemArrowType === ARROW_TYPE.sharp
? ARROW_TYPE.round
: prevState.currentItemArrowType === ARROW_TYPE.round
? ARROW_TYPE.elbow
: ARROW_TYPE.sharp,
}));
}
if (shape === "lasso" && this.state.activeTool.type === "laser") {
this.setActiveTool({
type: this.state.preferredSelectionTool.type,
});
} else {
this.setActiveTool({ type: shape });
}
event.stopPropagation();
return;
} else if (event.key === KEYS.Q) {
this.toggleLock("keyboard");
event.stopPropagation();
return;
}
}
if (this.state.viewModeEnabled) { if (this.state.viewModeEnabled) {
return; return;
} }
if (event[KEYS.CTRL_OR_CMD] && !event.repeat) { if (event[KEYS.CTRL_OR_CMD] && this.state.isBindingEnabled) {
if (getFeatureFlag("COMPLEX_BINDINGS")) { if (getFeatureFlag("COMPLEX_BINDINGS")) {
this.resetDelayedBindMode(); this.resetDelayedBindMode();
} }
flushSync(() => { flushSync(() => {
this.setState({ this.setState({ isBindingEnabled: false });
isBindingEnabled: this.state.bindingPreference !== "enabled",
});
}); });
maybeHandleArrowPointlikeDrag({ app: this, event }); maybeHandleArrowPointlikeDrag({ app: this, event });
@@ -5071,8 +4977,44 @@ class App extends React.Component<AppProps, AppState> {
}); });
} }
} }
} else if (
!event.ctrlKey &&
!event.altKey &&
!event.metaKey &&
!this.state.newElement &&
!this.state.selectionElement &&
!this.state.selectedElementsAreBeingDragged
) {
const shape = findShapeByKey(event.key, this);
if (shape) {
if (this.state.activeTool.type !== shape) {
trackEvent(
"toolbar",
shape,
`keyboard (${
this.editorInterface.formFactor === "phone"
? "mobile"
: "desktop"
})`,
);
}
if (shape === "arrow" && this.state.activeTool.type === "arrow") {
this.setState((prevState) => ({
currentItemArrowType:
prevState.currentItemArrowType === ARROW_TYPE.sharp
? ARROW_TYPE.round
: prevState.currentItemArrowType === ARROW_TYPE.round
? ARROW_TYPE.elbow
: ARROW_TYPE.sharp,
}));
}
this.setActiveTool({ type: shape });
event.stopPropagation();
} else if (event.key === KEYS.Q) {
this.toggleLock("keyboard");
event.stopPropagation();
}
} }
if (event.key === KEYS.SPACE && gesture.pointers.size === 0) { if (event.key === KEYS.SPACE && gesture.pointers.size === 0) {
isHoldingSpace = true; isHoldingSpace = true;
setCursor(this.interactiveCanvas, CURSOR_TYPE.GRAB); setCursor(this.interactiveCanvas, CURSOR_TYPE.GRAB);
@@ -5136,6 +5078,15 @@ class App extends React.Component<AppProps, AppState> {
} }
} }
if (event.key === KEYS.K && !event.altKey && !event[KEYS.CTRL_OR_CMD]) {
if (this.state.activeTool.type === "laser") {
this.setActiveTool({ type: this.state.preferredSelectionTool.type });
} else {
this.setActiveTool({ type: "laser" });
}
return;
}
if ( if (
event[KEYS.CTRL_OR_CMD] && event[KEYS.CTRL_OR_CMD] &&
(event.key === KEYS.BACKSPACE || event.key === KEYS.DELETE) (event.key === KEYS.BACKSPACE || event.key === KEYS.DELETE)
@@ -5162,8 +5113,7 @@ class App extends React.Component<AppProps, AppState> {
private onKeyUp = withBatchedUpdates((event: KeyboardEvent) => { private onKeyUp = withBatchedUpdates((event: KeyboardEvent) => {
if (event.key === KEYS.SPACE) { if (event.key === KEYS.SPACE) {
if ( if (
(this.state.viewModeEnabled && this.state.viewModeEnabled ||
this.state.activeTool.type !== "laser") ||
this.state.openDialog?.name === "elementLinkSelector" this.state.openDialog?.name === "elementLinkSelector"
) { ) {
setCursor(this.interactiveCanvas, CURSOR_TYPE.GRAB); setCursor(this.interactiveCanvas, CURSOR_TYPE.GRAB);
@@ -5222,13 +5172,10 @@ class App extends React.Component<AppProps, AppState> {
} }
} }
} }
if (!event[KEYS.CTRL_OR_CMD]) { if (!event[KEYS.CTRL_OR_CMD] && !this.state.isBindingEnabled) {
const preferenceEnabled = this.state.bindingPreference === "enabled"; flushSync(() => {
if (this.state.isBindingEnabled !== preferenceEnabled) { this.setState({ isBindingEnabled: true });
flushSync(() => { });
this.setState({ isBindingEnabled: preferenceEnabled });
});
}
maybeHandleArrowPointlikeDrag({ app: this, event }); maybeHandleArrowPointlikeDrag({ app: this, event });
} }
@@ -6280,8 +6227,9 @@ class App extends React.Component<AppProps, AppState> {
} }
}; };
private handleElementLinkClick = ( private redirectToLink = (
event: React.PointerEvent<HTMLCanvasElement>, event: React.PointerEvent<HTMLCanvasElement>,
isTouchScreen: boolean,
) => { ) => {
const draggedDistance = pointDistance( const draggedDistance = pointDistance(
pointFrom( pointFrom(
@@ -6855,10 +6803,6 @@ class App extends React.Component<AppProps, AppState> {
} }
} }
if (isEraserActive(this.state)) {
return;
}
const hitElementMightBeLocked = this.getElementAtPosition( const hitElementMightBeLocked = this.getElementAtPosition(
scenePointerX, scenePointerX,
scenePointerY, scenePointerY,
@@ -6875,25 +6819,18 @@ class App extends React.Component<AppProps, AppState> {
hitElement = hitElementMightBeLocked; hitElement = hitElementMightBeLocked;
} }
if ( this.hitLinkElement = this.getElementLinkAtPosition(
!this.handleIframeLikeElementHover({ scenePointer,
hitElement, hitElementMightBeLocked,
scenePointer, );
moveEvent: event, if (isEraserActive(this.state)) {
}) return;
) {
this.hitLinkElement = this.getElementLinkAtPosition(
scenePointer,
hitElementMightBeLocked,
);
} }
if ( if (
this.hitLinkElement && this.hitLinkElement &&
!this.state.selectedElementIds[this.hitLinkElement.id] !this.state.selectedElementIds[this.hitLinkElement.id]
) { ) {
setCursor(this.interactiveCanvas, CURSOR_TYPE.POINTER); setCursor(this.interactiveCanvas, CURSOR_TYPE.POINTER);
showHyperlinkTooltip( showHyperlinkTooltip(
this.hitLinkElement, this.hitLinkElement,
this.state, this.state,
@@ -6902,6 +6839,11 @@ class App extends React.Component<AppProps, AppState> {
} else { } else {
hideHyperlinkToolip(); hideHyperlinkToolip();
if (isLaserTool) { if (isLaserTool) {
this.handleIframeLikeElementHover({
hitElement,
scenePointer,
moveEvent: event,
});
return; return;
} }
if ( if (
@@ -6936,10 +6878,15 @@ class App extends React.Component<AppProps, AppState> {
!hitElement?.locked !hitElement?.locked
) { ) {
if ( if (
!hitElement || !this.handleIframeLikeElementHover({
// Elbow arrows can only be moved when unconnected hitElement,
!isElbowArrow(hitElement) || scenePointer,
!(hitElement.startBinding || hitElement.endBinding) moveEvent: event,
}) &&
(!hitElement ||
// Elbow arrows can only be moved when unconnected
!isElbowArrow(hitElement) ||
!(hitElement.startBinding || hitElement.endBinding))
) { ) {
if ( if (
this.state.activeTool.type !== "lasso" || this.state.activeTool.type !== "lasso" ||
@@ -7146,14 +7093,6 @@ class App extends React.Component<AppProps, AppState> {
private handleCanvasPointerDown = ( private handleCanvasPointerDown = (
event: React.PointerEvent<HTMLElement>, event: React.PointerEvent<HTMLElement>,
) => { ) => {
// If Ctrl is not held, ensure isBindingEnabled reflects the user preference.
if (!event.ctrlKey) {
const preferenceEnabled = this.state.bindingPreference === "enabled";
if (this.state.isBindingEnabled !== preferenceEnabled) {
this.setState({ isBindingEnabled: preferenceEnabled });
}
}
const scenePointer = viewportCoordsToSceneCoords(event, this.state); const scenePointer = viewportCoordsToSceneCoords(event, this.state);
const { x: scenePointerX, y: scenePointerY } = scenePointer; const { x: scenePointerX, y: scenePointerY } = scenePointer;
this.lastPointerMoveCoords = { this.lastPointerMoveCoords = {
@@ -7374,6 +7313,7 @@ class App extends React.Component<AppProps, AppState> {
} }
this.clearSelectionIfNotUsingSelection(); this.clearSelectionIfNotUsingSelection();
this.updateBindingEnabledOnPointerMove(event);
if (this.handleSelectionOnPointerDown(event, pointerDownState)) { if (this.handleSelectionOnPointerDown(event, pointerDownState)) {
return; return;
@@ -7596,13 +7536,6 @@ class App extends React.Component<AppProps, AppState> {
this.removePointer(event); this.removePointer(event);
this.lastPointerUpEvent = event; this.lastPointerUpEvent = event;
if (!event.ctrlKey) {
const preferenceEnabled = this.state.bindingPreference === "enabled";
if (this.state.isBindingEnabled !== preferenceEnabled) {
this.setState({ isBindingEnabled: preferenceEnabled });
}
}
const scenePointer = viewportCoordsToSceneCoords( const scenePointer = viewportCoordsToSceneCoords(
{ clientX: event.clientX, clientY: event.clientY }, { clientX: event.clientX, clientY: event.clientY },
this.state, this.state,
@@ -7635,7 +7568,7 @@ class App extends React.Component<AppProps, AppState> {
this.hitLinkElement && this.hitLinkElement &&
!this.state.selectedElementIds[this.hitLinkElement.id] !this.state.selectedElementIds[this.hitLinkElement.id]
) { ) {
this.handleElementLinkClick(event); this.redirectToLink(event, this.editorInterface.isTouchScreen);
} else if (this.state.viewModeEnabled) { } else if (this.state.viewModeEnabled) {
this.setState({ this.setState({
activeEmbeddable: null, activeEmbeddable: null,
@@ -7695,8 +7628,7 @@ class App extends React.Component<AppProps, AppState> {
(event.button === POINTER_BUTTON.WHEEL || (event.button === POINTER_BUTTON.WHEEL ||
(event.button === POINTER_BUTTON.MAIN && isHoldingSpace) || (event.button === POINTER_BUTTON.MAIN && isHoldingSpace) ||
isHandToolActive(this.state) || isHandToolActive(this.state) ||
(this.state.viewModeEnabled && this.state.viewModeEnabled)
this.state.activeTool.type !== "laser"))
) )
) { ) {
return false; return false;
@@ -7774,10 +7706,7 @@ class App extends React.Component<AppProps, AppState> {
lastPointerUp = null; lastPointerUp = null;
isPanning = false; isPanning = false;
if (!isHoldingSpace) { if (!isHoldingSpace) {
if ( if (this.state.viewModeEnabled) {
this.state.viewModeEnabled &&
this.state.activeTool.type !== "laser"
) {
setCursor(this.interactiveCanvas, CURSOR_TYPE.GRAB); setCursor(this.interactiveCanvas, CURSOR_TYPE.GRAB);
} else { } else {
setCursorForShape(this.interactiveCanvas, this.state); setCursorForShape(this.interactiveCanvas, this.state);
@@ -8658,9 +8587,7 @@ class App extends React.Component<AppProps, AppState> {
): void => { ): void => {
if (event.ctrlKey) { if (event.ctrlKey) {
flushSync(() => { flushSync(() => {
this.setState({ this.setState({ isBindingEnabled: false });
isBindingEnabled: this.state.bindingPreference !== "enabled",
});
}); });
} }
@@ -11354,6 +11281,15 @@ class App extends React.Component<AppProps, AppState> {
this.addNewImagesToImageCache(); this.addNewImagesToImageCache();
}, IMAGE_RENDER_TIMEOUT); }, IMAGE_RENDER_TIMEOUT);
private updateBindingEnabledOnPointerMove = (
event: React.PointerEvent<HTMLElement>,
) => {
const shouldEnableBinding = shouldEnableBindingForPointerEvent(event);
if (this.state.isBindingEnabled !== shouldEnableBinding) {
this.setState({ isBindingEnabled: shouldEnableBinding });
}
};
private clearSelection(hitElement: ExcalidrawElement | null): void { private clearSelection(hitElement: ExcalidrawElement | null): void {
this.setState((prevState) => ({ this.setState((prevState) => ({
selectedElementIds: makeNextSelectedElementIds({}, prevState), selectedElementIds: makeNextSelectedElementIds({}, prevState),
@@ -12115,8 +12051,6 @@ class App extends React.Component<AppProps, AppState> {
CONTEXT_MENU_SEPARATOR, CONTEXT_MENU_SEPARATOR,
actionToggleGridMode, actionToggleGridMode,
actionToggleObjectsSnapMode, actionToggleObjectsSnapMode,
actionToggleArrowBinding,
actionToggleMidpointSnapping,
actionToggleZenMode, actionToggleZenMode,
actionToggleViewMode, actionToggleViewMode,
actionToggleStats, actionToggleStats,
@@ -15,7 +15,7 @@ export type CommandPaletteItem = {
category: string; category: string;
order?: number; order?: number;
predicate?: boolean | Action["predicate"]; predicate?: boolean | Action["predicate"];
shortcut?: string | null; shortcut?: string;
/** if false, command will not show while in view mode */ /** if false, command will not show while in view mode */
viewMode?: boolean; viewMode?: boolean;
perform: (data: { perform: (data: {
+13 -4
View File
@@ -20,6 +20,7 @@ import type { NonDeletedExcalidrawElement } from "@excalidraw/element/types";
import { actionToggleStats } from "../actions"; import { actionToggleStats } from "../actions";
import { trackEvent } from "../analytics"; import { trackEvent } from "../analytics";
import { isHandToolActive } from "../appState";
import { TunnelsContext, useInitializeTunnels } from "../context/tunnels"; import { TunnelsContext, useInitializeTunnels } from "../context/tunnels";
import { UIAppStateContext } from "../context/ui-appState"; import { UIAppStateContext } from "../context/ui-appState";
import { useAtom, useAtomValue } from "../editor-jotai"; import { useAtom, useAtomValue } from "../editor-jotai";
@@ -54,6 +55,7 @@ import ElementLinkDialog from "./ElementLinkDialog";
import { ErrorDialog } from "./ErrorDialog"; import { ErrorDialog } from "./ErrorDialog";
import { EyeDropper, activeEyeDropperAtom } from "./EyeDropper"; import { EyeDropper, activeEyeDropperAtom } from "./EyeDropper";
import { FixedSideContainer } from "./FixedSideContainer"; import { FixedSideContainer } from "./FixedSideContainer";
import { HandButton } from "./HandButton";
import { HelpDialog } from "./HelpDialog"; import { HelpDialog } from "./HelpDialog";
import { HintViewer } from "./HintViewer"; import { HintViewer } from "./HintViewer";
import { ImageExportDialog } from "./ImageExportDialog"; import { ImageExportDialog } from "./ImageExportDialog";
@@ -357,6 +359,13 @@ const LayerUI = ({
<div className="App-toolbar__divider" /> <div className="App-toolbar__divider" />
<HandButton
checked={isHandToolActive(appState)}
onChange={() => onHandToolToggle()}
title={t("toolBar.hand")}
isMobile
/>
<ShapesSwitcher <ShapesSwitcher
setAppState={setAppState} setAppState={setAppState}
activeTool={appState.activeTool} activeTool={appState.activeTool}
@@ -556,13 +565,13 @@ const LayerUI = ({
<tunnels.OverwriteConfirmDialogTunnel.Out /> <tunnels.OverwriteConfirmDialogTunnel.Out />
{renderImageExportDialog()} {renderImageExportDialog()}
{renderJSONExportDialog()} {renderJSONExportDialog()}
{appState.openDialog?.name === "charts" && ( {appState.pasteDialog.shown && (
<PasteChartDialog <PasteChartDialog
data={appState.openDialog.data} setAppState={setAppState}
rawText={appState.openDialog.rawText} appState={appState}
onClose={() => onClose={() =>
setAppState({ setAppState({
openDialog: null, pasteDialog: { shown: false, data: null },
}) })
} }
/> />
@@ -2,40 +2,6 @@
.excalidraw { .excalidraw {
.PasteChartDialog { .PasteChartDialog {
.PasteChartDialog__title {
display: flex;
align-items: center;
gap: 0.5rem;
}
.PasteChartDialog__titleText {
min-width: 0;
}
.PasteChartDialog__reshuffleBtn {
margin-left: auto;
flex: 0 0 auto;
width: 1rem;
height: 1rem;
display: inline-flex;
align-items: center;
justify-content: center;
border-radius: 4px;
cursor: pointer;
color: var(--text-primary-color);
transition: transform 120ms ease, background-color 120ms ease,
color 120ms ease;
user-select: none;
&:hover {
color: $color-blue-6;
}
&:active {
transform: scale(0.94);
}
}
@include isMobile { @include isMobile {
.Island { .Island {
display: flex; display: flex;
@@ -45,61 +11,35 @@
.container { .container {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: space-around;
flex-wrap: wrap; flex-wrap: wrap;
gap: 1rem;
@include isMobile { @include isMobile {
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
align-items: stretch;
} }
} }
.ChartPreview { .ChartPreview {
width: 260px; margin: 8px;
min-height: 190px; text-align: center;
border-radius: 8px; width: 192px;
padding: 10px; height: 128px;
border-radius: 2px;
padding: 1px;
border: 1px solid $color-gray-4; border: 1px solid $color-gray-4;
display: flex; display: flex;
flex-direction: column; align-items: center;
align-items: stretch; justify-content: center;
justify-content: flex-start;
gap: 10px;
background: transparent; background: transparent;
.ChartPreview__canvas { div {
display: flex; display: inline-block;
flex: 1;
align-items: center;
justify-content: center;
overflow: hidden;
}
.ChartPreview__label {
font-size: 0.875rem;
font-weight: 600;
line-height: 1;
text-align: center;
color: var(--text-primary-color);
} }
svg { svg {
max-height: 144px; max-height: 120px;
max-width: 100%; max-width: 186px;
} }
&:hover { &:hover {
border-color: $color-blue-5; padding: 0;
} border: 2px solid $color-blue-5;
&:active {
border-color: $color-blue-5;
box-shadow: 0 0 0 1px $color-blue-5;
transform: scale(0.98);
}
&:focus-visible {
border-color: $color-blue-5;
box-shadow: 0 0 0 1px $color-blue-5;
}
@include isMobile {
width: 100%;
min-height: 200px;
} }
} }
} }
@@ -1,57 +1,35 @@
import React, { useLayoutEffect, useRef, useState } from "react"; import React, { useLayoutEffect, useRef, useState } from "react";
import { newTextElement } from "@excalidraw/element";
import type { ChartType } from "@excalidraw/element/types"; import type { ChartType } from "@excalidraw/element/types";
import { trackEvent } from "../analytics"; import { trackEvent } from "../analytics";
import { isSpreadsheetValidForChartType, renderSpreadsheet } from "../charts"; import { renderSpreadsheet } from "../charts";
import { t } from "../i18n"; import { t } from "../i18n";
import { exportToSvg } from "../scene/export"; import { exportToSvg } from "../scene/export";
import { useUIAppState } from "../context/ui-appState";
import { useApp } from "./App"; import { useApp } from "./App";
import { Dialog } from "./Dialog"; import { Dialog } from "./Dialog";
import "./PasteChartDialog.scss"; import "./PasteChartDialog.scss";
import { bucketFillIcon } from "./icons";
import type { ChartElements, Spreadsheet } from "../charts"; import type { ChartElements, Spreadsheet } from "../charts";
import type { UIAppState } from "../types";
type OnPlainTextPaste = (rawText: string) => void;
type OnInsertChart = (chartType: ChartType, elements: ChartElements) => void; type OnInsertChart = (chartType: ChartType, elements: ChartElements) => void;
const getChartTypeLabel = (chartType: ChartType) => {
switch (chartType) {
case "bar":
return t("labels.chartType_bar");
case "line":
return t("labels.chartType_line");
case "radar":
return t("labels.chartType_radar");
default:
return chartType;
}
};
const ChartPreviewBtn = (props: { const ChartPreviewBtn = (props: {
spreadsheet: Spreadsheet | null; spreadsheet: Spreadsheet | null;
chartType: ChartType; chartType: ChartType;
colorSeed: number; selected: boolean;
onClick: OnInsertChart; onClick: OnInsertChart;
}) => { }) => {
const previewRef = useRef<HTMLDivElement | null>(null); const previewRef = useRef<HTMLDivElement | null>(null);
const [chartElements, setChartElements] = useState<ChartElements | null>( const [chartElements, setChartElements] = useState<ChartElements | null>(
null, null,
); );
const { theme } = useUIAppState();
useLayoutEffect(() => { useLayoutEffect(() => {
if (!props.spreadsheet) { if (!props.spreadsheet) {
setChartElements(null);
return; return;
} }
@@ -60,13 +38,7 @@ const ChartPreviewBtn = (props: {
props.spreadsheet, props.spreadsheet,
0, 0,
0, 0,
props.colorSeed,
); );
if (!elements) {
setChartElements(null);
previewRef.current?.replaceChildren();
return;
}
setChartElements(elements); setChartElements(elements);
let svg: SVGSVGElement; let svg: SVGSVGElement;
const previewNode = previewRef.current!; const previewNode = previewRef.current!;
@@ -77,7 +49,6 @@ const ChartPreviewBtn = (props: {
{ {
exportBackground: false, exportBackground: false,
viewBackgroundColor: "#fff", viewBackgroundColor: "#fff",
exportWithDarkMode: theme === "dark",
}, },
null, // files null, // files
{ {
@@ -87,108 +58,42 @@ const ChartPreviewBtn = (props: {
svg.querySelector(".style-fonts")?.remove(); svg.querySelector(".style-fonts")?.remove();
previewNode.replaceChildren(); previewNode.replaceChildren();
previewNode.appendChild(svg); previewNode.appendChild(svg);
if (props.selected) {
(previewNode.parentNode as HTMLDivElement).focus();
}
})(); })();
return () => { return () => {
previewNode.replaceChildren(); previewNode.replaceChildren();
}; };
}, [props.spreadsheet, props.chartType, props.colorSeed, theme]); }, [props.spreadsheet, props.chartType, props.selected]);
const chartTypeLabel = getChartTypeLabel(props.chartType);
return ( return (
<button <button
type="button" type="button"
className="ChartPreview" className="ChartPreview"
aria-label={chartTypeLabel}
onClick={() => { onClick={() => {
if (chartElements) { if (chartElements) {
props.onClick(props.chartType, chartElements); props.onClick(props.chartType, chartElements);
} }
}} }}
> >
<div className="ChartPreview__canvas" ref={previewRef} /> <div ref={previewRef} />
<div className="ChartPreview__label">{chartTypeLabel}</div>
</button>
);
};
const PlainTextPreviewBtn = (props: {
rawText: string;
onClick: OnPlainTextPaste;
}) => {
const previewRef = useRef<HTMLDivElement | null>(null);
const { theme } = useUIAppState();
useLayoutEffect(() => {
if (!props.rawText) {
return;
}
const textElement = newTextElement({
text: props.rawText,
x: 0,
y: 0,
});
const previewNode = previewRef.current!;
(async () => {
const svg = await exportToSvg(
[textElement],
{
exportBackground: false,
viewBackgroundColor: "#fff",
exportWithDarkMode: theme === "dark",
},
null,
{
skipInliningFonts: true,
},
);
svg.querySelector(".style-fonts")?.remove();
previewNode.replaceChildren();
previewNode.appendChild(svg);
})();
return () => {
previewNode.replaceChildren();
};
}, [props.rawText, theme]);
return (
<button
type="button"
className="ChartPreview"
aria-label={t("labels.chartType_plaintext")}
onClick={() => {
props.onClick(props.rawText);
}}
>
<div className="ChartPreview__canvas" ref={previewRef} />
<div className="ChartPreview__label">
{t("labels.chartType_plaintext")}
</div>
</button> </button>
); );
}; };
export const PasteChartDialog = ({ export const PasteChartDialog = ({
data, setAppState,
rawText, appState,
onClose, onClose,
}: { }: {
data: Spreadsheet; appState: UIAppState;
rawText: string;
onClose: () => void; onClose: () => void;
setAppState: React.Component<any, UIAppState>["setState"];
}) => { }) => {
const { onInsertElements, focusContainer } = useApp(); const { onInsertElements } = useApp();
const [colorSeed, setColorSeed] = useState(Math.random());
const handleReshuffleColors = React.useCallback(() => {
setColorSeed(Math.random());
}, []);
const handleClose = React.useCallback(() => { const handleClose = React.useCallback(() => {
if (onClose) { if (onClose) {
onClose(); onClose();
@@ -198,72 +103,36 @@ export const PasteChartDialog = ({
const handleChartClick = (chartType: ChartType, elements: ChartElements) => { const handleChartClick = (chartType: ChartType, elements: ChartElements) => {
onInsertElements(elements); onInsertElements(elements);
trackEvent("paste", "chart", chartType); trackEvent("paste", "chart", chartType);
onClose(); setAppState({
focusContainer(); currentChartType: chartType,
}; pasteDialog: {
shown: false,
const handlePlainTextClick = (rawText: string) => { data: null,
const textElement = newTextElement({ },
text: rawText,
x: 0,
y: 0,
}); });
onInsertElements([textElement]);
trackEvent("paste", "chart", "plaintext");
onClose();
focusContainer();
}; };
return ( return (
<Dialog <Dialog
size="regular" size="small"
onCloseRequest={handleClose} onCloseRequest={handleClose}
title={ title={t("labels.pasteCharts")}
<div className="PasteChartDialog__title">
<div className="PasteChartDialog__titleText">
{t("labels.pasteCharts")}
</div>
<div
className="PasteChartDialog__reshuffleBtn"
onClick={handleReshuffleColors}
role="button"
tabIndex={0}
onKeyDown={(event) => {
if (event.key === "Enter" || event.key === " ") {
event.preventDefault();
handleReshuffleColors();
}
}}
>
{bucketFillIcon}
</div>
</div>
}
className={"PasteChartDialog"} className={"PasteChartDialog"}
autofocus={false} autofocus={false}
> >
<div className={"container"}> <div className={"container"}>
{(["bar", "line", "radar"] as const).map((chartType) => { <ChartPreviewBtn
if (!isSpreadsheetValidForChartType(data, chartType)) { chartType="bar"
return null; spreadsheet={appState.pasteDialog.data}
} selected={appState.currentChartType === "bar"}
onClick={handleChartClick}
return ( />
<ChartPreviewBtn <ChartPreviewBtn
key={chartType} chartType="line"
chartType={chartType} spreadsheet={appState.pasteDialog.data}
spreadsheet={data} selected={appState.currentChartType === "line"}
colorSeed={colorSeed} onClick={handleChartClick}
onClick={handleChartClick} />
/>
);
})}
{rawText && (
<PlainTextPreviewBtn
rawText={rawText}
onClick={handlePlainTextClick}
/>
)}
</div> </div>
</Dialog> </Dialog>
); );
@@ -202,11 +202,9 @@ const InteractiveCanvas = (props: InteractiveCanvasProps) => {
style={{ style={{
width: props.appState.width, width: props.appState.width,
height: props.appState.height, height: props.appState.height,
cursor: cursor: props.appState.viewModeEnabled
props.appState.viewModeEnabled && ? CURSOR_TYPE.GRAB
props.appState.activeTool.type !== "laser" : CURSOR_TYPE.AUTO,
? CURSOR_TYPE.GRAB
: CURSOR_TYPE.AUTO,
}} }}
width={props.appState.width * props.scale} width={props.appState.width * props.scale}
height={props.appState.height * props.scale} height={props.appState.height * props.scale}
@@ -235,7 +233,6 @@ const getRelevantAppStateProps = (
width: appState.width, width: appState.width,
height: appState.height, height: appState.height,
viewModeEnabled: appState.viewModeEnabled, viewModeEnabled: appState.viewModeEnabled,
activeTool: appState.activeTool,
openDialog: appState.openDialog, openDialog: appState.openDialog,
editingGroupId: appState.editingGroupId, editingGroupId: appState.editingGroupId,
selectedElementIds: appState.selectedElementIds, selectedElementIds: appState.selectedElementIds,
@@ -249,7 +246,6 @@ const getRelevantAppStateProps = (
multiElement: appState.multiElement, multiElement: appState.multiElement,
newElement: appState.newElement, newElement: appState.newElement,
isBindingEnabled: appState.isBindingEnabled, isBindingEnabled: appState.isBindingEnabled,
isMidpointSnappingEnabled: appState.isMidpointSnappingEnabled,
suggestedBinding: appState.suggestedBinding, suggestedBinding: appState.suggestedBinding,
isRotating: appState.isRotating, isRotating: appState.isRotating,
elementsToHighlight: appState.elementsToHighlight, elementsToHighlight: appState.elementsToHighlight,
@@ -266,7 +262,6 @@ const getRelevantAppStateProps = (
frameRendering: appState.frameRendering, frameRendering: appState.frameRendering,
shouldCacheIgnoreZoom: appState.shouldCacheIgnoreZoom, shouldCacheIgnoreZoom: appState.shouldCacheIgnoreZoom,
exportScale: appState.exportScale, exportScale: appState.exportScale,
currentItemArrowType: appState.currentItemArrowType,
}); });
const areEqual = ( const areEqual = (
@@ -181,21 +181,6 @@
box-shadow: 0 0 0 1px var(--color-brand-active); box-shadow: 0 0 0 1px var(--color-brand-active);
} }
&[disabled] {
cursor: not-allowed;
opacity: 0.5;
pointer-events: none;
&:hover {
background-color: transparent;
}
&:active {
background-color: transparent;
box-shadow: none;
}
}
svg { svg {
width: 1rem; width: 1rem;
height: 1rem; height: 1rem;
@@ -9,9 +9,7 @@ import {
actionLoadScene, actionLoadScene,
actionSaveToActiveFile, actionSaveToActiveFile,
actionShortcuts, actionShortcuts,
actionToggleArrowBinding,
actionToggleGridMode, actionToggleGridMode,
actionToggleMidpointSnapping,
actionToggleObjectsSnapMode, actionToggleObjectsSnapMode,
actionToggleSearchMenu, actionToggleSearchMenu,
actionToggleStats, actionToggleStats,
@@ -445,41 +443,6 @@ const PreferencesToggleSnapModeItem = () => {
); );
}; };
const PreferencesToggleArrowBindingItem = () => {
const { t } = useI18n();
const actionManager = useExcalidrawActionManager();
const appState = useUIAppState();
return (
<DropdownMenuItemCheckbox
checked={appState.bindingPreference === "enabled"}
onSelect={(event) => {
actionManager.executeAction(actionToggleArrowBinding);
event.preventDefault();
}}
>
{t("labels.arrowBinding")}
</DropdownMenuItemCheckbox>
);
};
const PreferencesToggleMidpointSnappingItem = () => {
const { t } = useI18n();
const actionManager = useExcalidrawActionManager();
const appState = useUIAppState();
return (
<DropdownMenuItemCheckbox
checked={appState.isMidpointSnappingEnabled}
disabled={appState.bindingPreference === "disabled"}
onSelect={(event) => {
actionManager.executeAction(actionToggleMidpointSnapping);
event.preventDefault();
}}
>
{t("labels.midpointSnapping")}
</DropdownMenuItemCheckbox>
);
};
export const PreferencesToggleGridModeItem = () => { export const PreferencesToggleGridModeItem = () => {
const { t } = useI18n(); const { t } = useI18n();
const actionManager = useExcalidrawActionManager(); const actionManager = useExcalidrawActionManager();
@@ -575,8 +538,6 @@ export const Preferences = ({
<PreferencesToggleZenModeItem /> <PreferencesToggleZenModeItem />
<PreferencesToggleViewModeItem /> <PreferencesToggleViewModeItem />
<PreferencesToggleElementPropertiesItem /> <PreferencesToggleElementPropertiesItem />
<PreferencesToggleArrowBindingItem />
<PreferencesToggleMidpointSnappingItem />
</> </>
)} )}
{additionalItems} {additionalItems}
@@ -587,8 +548,6 @@ export const Preferences = ({
Preferences.ToggleToolLock = PreferencesToggleToolLockItem; Preferences.ToggleToolLock = PreferencesToggleToolLockItem;
Preferences.ToggleSnapMode = PreferencesToggleSnapModeItem; Preferences.ToggleSnapMode = PreferencesToggleSnapModeItem;
Preferences.ToggleArrowBinding = PreferencesToggleArrowBindingItem;
Preferences.ToggleMidpointSnapping = PreferencesToggleMidpointSnappingItem;
Preferences.ToggleGridMode = PreferencesToggleGridModeItem; Preferences.ToggleGridMode = PreferencesToggleGridModeItem;
Preferences.ToggleZenMode = PreferencesToggleZenModeItem; Preferences.ToggleZenMode = PreferencesToggleZenModeItem;
Preferences.ToggleViewMode = PreferencesToggleViewModeItem; Preferences.ToggleViewMode = PreferencesToggleViewModeItem;
-29
View File
@@ -11,28 +11,17 @@ import {
TextIcon, TextIcon,
ImageIcon, ImageIcon,
EraserIcon, EraserIcon,
laserPointerToolIcon,
handIcon,
} from "./icons"; } from "./icons";
import type { AppClassProperties } from "../types"; import type { AppClassProperties } from "../types";
export const SHAPES = [ export const SHAPES = [
{
icon: handIcon,
value: "hand",
key: KEYS.H,
numericKey: null,
fillable: false,
toolbar: true,
},
{ {
icon: SelectionIcon, icon: SelectionIcon,
value: "selection", value: "selection",
key: KEYS.V, key: KEYS.V,
numericKey: KEYS["1"], numericKey: KEYS["1"],
fillable: true, fillable: true,
toolbar: true,
}, },
{ {
icon: RectangleIcon, icon: RectangleIcon,
@@ -40,7 +29,6 @@ export const SHAPES = [
key: KEYS.R, key: KEYS.R,
numericKey: KEYS["2"], numericKey: KEYS["2"],
fillable: true, fillable: true,
toolbar: true,
}, },
{ {
icon: DiamondIcon, icon: DiamondIcon,
@@ -48,7 +36,6 @@ export const SHAPES = [
key: KEYS.D, key: KEYS.D,
numericKey: KEYS["3"], numericKey: KEYS["3"],
fillable: true, fillable: true,
toolbar: true,
}, },
{ {
icon: EllipseIcon, icon: EllipseIcon,
@@ -56,7 +43,6 @@ export const SHAPES = [
key: KEYS.O, key: KEYS.O,
numericKey: KEYS["4"], numericKey: KEYS["4"],
fillable: true, fillable: true,
toolbar: true,
}, },
{ {
icon: ArrowIcon, icon: ArrowIcon,
@@ -64,7 +50,6 @@ export const SHAPES = [
key: KEYS.A, key: KEYS.A,
numericKey: KEYS["5"], numericKey: KEYS["5"],
fillable: true, fillable: true,
toolbar: true,
}, },
{ {
icon: LineIcon, icon: LineIcon,
@@ -72,7 +57,6 @@ export const SHAPES = [
key: KEYS.L, key: KEYS.L,
numericKey: KEYS["6"], numericKey: KEYS["6"],
fillable: true, fillable: true,
toolbar: true,
}, },
{ {
icon: FreedrawIcon, icon: FreedrawIcon,
@@ -80,7 +64,6 @@ export const SHAPES = [
key: [KEYS.P, KEYS.X], key: [KEYS.P, KEYS.X],
numericKey: KEYS["7"], numericKey: KEYS["7"],
fillable: false, fillable: false,
toolbar: true,
}, },
{ {
icon: TextIcon, icon: TextIcon,
@@ -88,7 +71,6 @@ export const SHAPES = [
key: KEYS.T, key: KEYS.T,
numericKey: KEYS["8"], numericKey: KEYS["8"],
fillable: false, fillable: false,
toolbar: true,
}, },
{ {
icon: ImageIcon, icon: ImageIcon,
@@ -96,7 +78,6 @@ export const SHAPES = [
key: null, key: null,
numericKey: KEYS["9"], numericKey: KEYS["9"],
fillable: false, fillable: false,
toolbar: true,
}, },
{ {
icon: EraserIcon, icon: EraserIcon,
@@ -104,15 +85,6 @@ export const SHAPES = [
key: KEYS.E, key: KEYS.E,
numericKey: KEYS["0"], numericKey: KEYS["0"],
fillable: false, fillable: false,
toolbar: true,
},
{
icon: laserPointerToolIcon,
value: "laser",
key: KEYS.K,
numericKey: null,
fillable: false,
toolbar: false,
}, },
] as const; ] as const;
@@ -125,7 +97,6 @@ export const getToolbarTools = (app: AppClassProperties) => {
key: KEYS.V, key: KEYS.V,
numericKey: KEYS["1"], numericKey: KEYS["1"],
fillable: true, fillable: true,
toolbar: true,
}, },
...SHAPES.slice(1), ...SHAPES.slice(1),
] as const) ] as const)
+11 -27
View File
@@ -155,7 +155,7 @@ const repairBinding = <T extends ExcalidrawArrowElement>(
| ExcalidrawElbowArrowElement["startBinding"] | ExcalidrawElbowArrowElement["startBinding"]
| ExcalidrawElbowArrowElement["endBinding"] = { | ExcalidrawElbowArrowElement["endBinding"] = {
...binding, ...binding,
fixedPoint: normalizeFixedPoint(binding.fixedPoint), fixedPoint: normalizeFixedPoint(binding.fixedPoint ?? [0, 0]),
mode: binding.mode || "orbit", mode: binding.mode || "orbit",
}; };
@@ -176,7 +176,7 @@ const repairBinding = <T extends ExcalidrawArrowElement>(
return { return {
elementId: binding.elementId, elementId: binding.elementId,
mode: binding.mode, mode: binding.mode,
fixedPoint: normalizeFixedPoint(binding.fixedPoint), fixedPoint: normalizeFixedPoint(binding.fixedPoint || [0.5, 0.5]),
} as FixedPointBinding | null; } as FixedPointBinding | null;
} }
return null; return null;
@@ -185,14 +185,15 @@ const repairBinding = <T extends ExcalidrawArrowElement>(
// binding schema v1 (legacy) -> attempt to migrate to v2 // binding schema v1 (legacy) -> attempt to migrate to v2
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
const targetBoundElement = targetElementsMap.get(binding.elementId) as const targetBoundElement =
| ExcalidrawBindableElement (targetElementsMap.get(binding.elementId) as ExcalidrawBindableElement) ||
| undefined; undefined;
const boundElement = const boundElement =
targetBoundElement || targetBoundElement ||
(existingElementsMap?.get(binding.elementId) as (existingElementsMap?.get(
| ExcalidrawBindableElement binding.elementId,
| undefined); ) as ExcalidrawBindableElement) ||
undefined;
const elementsMap = targetBoundElement const elementsMap = targetBoundElement
? targetElementsMap ? targetElementsMap
: existingElementsMap; : existingElementsMap;
@@ -207,28 +208,11 @@ const repairBinding = <T extends ExcalidrawArrowElement>(
const mode = isPointInElement(p, boundElement, elementsMap) const mode = isPointInElement(p, boundElement, elementsMap)
? "inside" ? "inside"
: "orbit"; : "orbit";
const safeElement = {
...element,
startBinding: element.startBinding?.elementId
? {
...element.startBinding,
mode,
fixedPoint: normalizeFixedPoint(element.startBinding.fixedPoint),
}
: null,
endBinding: element.endBinding?.elementId
? {
...element.endBinding,
mode,
fixedPoint: normalizeFixedPoint(element.endBinding.fixedPoint),
}
: null,
};
const focusPoint = const focusPoint =
mode === "inside" mode === "inside"
? p ? p
: projectFixedPointOntoDiagonal( : projectFixedPointOntoDiagonal(
safeElement, element,
p, p,
boundElement, boundElement,
startOrEnd, startOrEnd,
@@ -236,7 +220,7 @@ const repairBinding = <T extends ExcalidrawArrowElement>(
{ value: 1 as NormalizedZoomValue }, { value: 1 as NormalizedZoomValue },
) || p; ) || p;
const { fixedPoint } = calculateFixedPointForNonElbowArrowBinding( const { fixedPoint } = calculateFixedPointForNonElbowArrowBinding(
safeElement, element,
boundElement, boundElement,
startOrEnd, startOrEnd,
elementsMap, elementsMap,
-6
View File
@@ -319,9 +319,3 @@ export { isElementLink } from "@excalidraw/element";
export { setCustomTextMetricsProvider } from "@excalidraw/element"; export { setCustomTextMetricsProvider } from "@excalidraw/element";
export { CommandPalette } from "./components/CommandPalette/CommandPalette"; export { CommandPalette } from "./components/CommandPalette/CommandPalette";
export {
renderSpreadsheet,
tryParseSpreadsheet,
isSpreadsheetValidForChartType,
} from "./charts";
+3 -23
View File
@@ -3,10 +3,6 @@
"paste": "لصق", "paste": "لصق",
"pasteAsPlaintext": "اللصق كنص عادي", "pasteAsPlaintext": "اللصق كنص عادي",
"pasteCharts": "لصق الرسوم البيانية", "pasteCharts": "لصق الرسوم البيانية",
"chartType_bar": "",
"chartType_line": "",
"chartType_radar": "",
"chartType_plaintext": "",
"selectAll": "تحديد الكل", "selectAll": "تحديد الكل",
"multiSelect": "إضافة عنصر للتحديد", "multiSelect": "إضافة عنصر للتحديد",
"moveCanvas": "نقل لوح الرسم", "moveCanvas": "نقل لوح الرسم",
@@ -53,14 +49,7 @@
"arrowhead_crowfoot_many": "Crow's foot (many)", "arrowhead_crowfoot_many": "Crow's foot (many)",
"arrowhead_crowfoot_one": "Crow's foot (one)", "arrowhead_crowfoot_one": "Crow's foot (one)",
"arrowhead_crowfoot_one_or_many": "Crow's foot (one or many)", "arrowhead_crowfoot_one_or_many": "Crow's foot (one or many)",
"arrowhead_cardinality_one": "",
"arrowhead_cardinality_many": "",
"arrowhead_cardinality_one_or_many": "",
"arrowhead_cardinality_exactly_one": "",
"arrowhead_cardinality_zero_or_one": "",
"arrowhead_cardinality_zero_or_many": "",
"more_options": "خيارات إضافية", "more_options": "خيارات إضافية",
"cardinality": "",
"arrowtypes": "نوع السهم", "arrowtypes": "نوع السهم",
"arrowtype_sharp": "سهم حاد", "arrowtype_sharp": "سهم حاد",
"arrowtype_round": "سهم منحني", "arrowtype_round": "سهم منحني",
@@ -182,11 +171,7 @@
"linkToElement": "رابط إلى الكائن", "linkToElement": "رابط إلى الكائن",
"wrapSelectionInFrame": "تغليف التحديد في إطار", "wrapSelectionInFrame": "تغليف التحديد في إطار",
"tab": "", "tab": "",
"shapeSwitch": "", "shapeSwitch": ""
"preferences": "",
"preferences_toolLock": "",
"arrowBinding": "",
"midpointSnapping": ""
}, },
"elementLink": { "elementLink": {
"title": "رابط إلى الكائن", "title": "رابط إلى الكائن",
@@ -410,10 +395,6 @@
"errorDialog": { "errorDialog": {
"title": "خطأ" "title": "خطأ"
}, },
"progressDialog": {
"title": "",
"defaultMessage": ""
},
"exportDialog": { "exportDialog": {
"disk_title": "حفظ الملف على الجهاز", "disk_title": "حفظ الملف على الجهاز",
"disk_details": "تصدير بيانات المشهد إلى ملف يمكنك الاستيراد منه لاحقًا.", "disk_details": "تصدير بيانات المشهد إلى ملف يمكنك الاستيراد منه لاحقًا.",
@@ -631,12 +612,11 @@
"mermaid": { "mermaid": {
"title": "Mermaid إلى Excalidraw", "title": "Mermaid إلى Excalidraw",
"button": "إدراج", "button": "إدراج",
"description": "", "description": "حاليًا، يتم دعم <flowchartLink>مخططات التدفق</flowchartLink>، <sequenceLink>التسلسلات</sequenceLink>، و<classLink>الفئات</classLink> فقط. سيتم عرض الأنواع الأخرى كصورة في Excalidraw.",
"syntax": "صيغة Mermaid", "syntax": "صيغة Mermaid",
"preview": "معاينة", "preview": "معاينة",
"label": "", "label": "",
"inputPlaceholder": "", "inputPlaceholder": ""
"autoFixAvailable": ""
}, },
"ttd": { "ttd": {
"error": "" "error": ""
+2 -22
View File
@@ -3,10 +3,6 @@
"paste": "Yapışdır", "paste": "Yapışdır",
"pasteAsPlaintext": "Düz mətn kimi yapışdırın", "pasteAsPlaintext": "Düz mətn kimi yapışdırın",
"pasteCharts": "Diaqramları yapışdırın", "pasteCharts": "Diaqramları yapışdırın",
"chartType_bar": "",
"chartType_line": "",
"chartType_radar": "",
"chartType_plaintext": "",
"selectAll": "Hamısını seç", "selectAll": "Hamısını seç",
"multiSelect": "Seçimə element əlavə edin", "multiSelect": "Seçimə element əlavə edin",
"moveCanvas": "Kanvası köçürün", "moveCanvas": "Kanvası köçürün",
@@ -53,14 +49,7 @@
"arrowhead_crowfoot_many": "", "arrowhead_crowfoot_many": "",
"arrowhead_crowfoot_one": "", "arrowhead_crowfoot_one": "",
"arrowhead_crowfoot_one_or_many": "", "arrowhead_crowfoot_one_or_many": "",
"arrowhead_cardinality_one": "",
"arrowhead_cardinality_many": "",
"arrowhead_cardinality_one_or_many": "",
"arrowhead_cardinality_exactly_one": "",
"arrowhead_cardinality_zero_or_one": "",
"arrowhead_cardinality_zero_or_many": "",
"more_options": "", "more_options": "",
"cardinality": "",
"arrowtypes": "", "arrowtypes": "",
"arrowtype_sharp": "", "arrowtype_sharp": "",
"arrowtype_round": "", "arrowtype_round": "",
@@ -182,11 +171,7 @@
"linkToElement": "", "linkToElement": "",
"wrapSelectionInFrame": "", "wrapSelectionInFrame": "",
"tab": "", "tab": "",
"shapeSwitch": "", "shapeSwitch": ""
"preferences": "",
"preferences_toolLock": "",
"arrowBinding": "",
"midpointSnapping": ""
}, },
"elementLink": { "elementLink": {
"title": "", "title": "",
@@ -410,10 +395,6 @@
"errorDialog": { "errorDialog": {
"title": "" "title": ""
}, },
"progressDialog": {
"title": "",
"defaultMessage": ""
},
"exportDialog": { "exportDialog": {
"disk_title": "", "disk_title": "",
"disk_details": "", "disk_details": "",
@@ -635,8 +616,7 @@
"syntax": "", "syntax": "",
"preview": "", "preview": "",
"label": "", "label": "",
"inputPlaceholder": "", "inputPlaceholder": ""
"autoFixAvailable": ""
}, },
"ttd": { "ttd": {
"error": "" "error": ""
+2 -22
View File
@@ -3,10 +3,6 @@
"paste": "Постави", "paste": "Постави",
"pasteAsPlaintext": "Постави като обикновен текст", "pasteAsPlaintext": "Постави като обикновен текст",
"pasteCharts": "Постави графики", "pasteCharts": "Постави графики",
"chartType_bar": "",
"chartType_line": "",
"chartType_radar": "",
"chartType_plaintext": "",
"selectAll": "Маркирай всичко", "selectAll": "Маркирай всичко",
"multiSelect": "Добави елемент към селекция", "multiSelect": "Добави елемент към селекция",
"moveCanvas": "Премести платно", "moveCanvas": "Премести платно",
@@ -53,14 +49,7 @@
"arrowhead_crowfoot_many": "", "arrowhead_crowfoot_many": "",
"arrowhead_crowfoot_one": "", "arrowhead_crowfoot_one": "",
"arrowhead_crowfoot_one_or_many": "", "arrowhead_crowfoot_one_or_many": "",
"arrowhead_cardinality_one": "",
"arrowhead_cardinality_many": "",
"arrowhead_cardinality_one_or_many": "",
"arrowhead_cardinality_exactly_one": "",
"arrowhead_cardinality_zero_or_one": "",
"arrowhead_cardinality_zero_or_many": "",
"more_options": "", "more_options": "",
"cardinality": "",
"arrowtypes": "Вид стрелка", "arrowtypes": "Вид стрелка",
"arrowtype_sharp": "Остра стрелка", "arrowtype_sharp": "Остра стрелка",
"arrowtype_round": "Извита стрелка", "arrowtype_round": "Извита стрелка",
@@ -182,11 +171,7 @@
"linkToElement": "", "linkToElement": "",
"wrapSelectionInFrame": "", "wrapSelectionInFrame": "",
"tab": "", "tab": "",
"shapeSwitch": "", "shapeSwitch": ""
"preferences": "",
"preferences_toolLock": "",
"arrowBinding": "",
"midpointSnapping": ""
}, },
"elementLink": { "elementLink": {
"title": "", "title": "",
@@ -410,10 +395,6 @@
"errorDialog": { "errorDialog": {
"title": "Грешка" "title": "Грешка"
}, },
"progressDialog": {
"title": "",
"defaultMessage": ""
},
"exportDialog": { "exportDialog": {
"disk_title": "Запази към диск", "disk_title": "Запази към диск",
"disk_details": "", "disk_details": "",
@@ -635,8 +616,7 @@
"syntax": "Mermaid Синтаксис", "syntax": "Mermaid Синтаксис",
"preview": "Преглед", "preview": "Преглед",
"label": "", "label": "",
"inputPlaceholder": "", "inputPlaceholder": ""
"autoFixAvailable": ""
}, },
"ttd": { "ttd": {
"error": "" "error": ""
+2 -22
View File
@@ -3,10 +3,6 @@
"paste": "পেস্ট করুন", "paste": "পেস্ট করুন",
"pasteAsPlaintext": "প্লেইনটেক্সট হিসাবে পেস্ট করুন", "pasteAsPlaintext": "প্লেইনটেক্সট হিসাবে পেস্ট করুন",
"pasteCharts": "চার্ট পেস্ট করুন", "pasteCharts": "চার্ট পেস্ট করুন",
"chartType_bar": "",
"chartType_line": "",
"chartType_radar": "",
"chartType_plaintext": "",
"selectAll": "সবটা সিলেক্ট করুন", "selectAll": "সবটা সিলেক্ট করুন",
"multiSelect": "একাধিক সিলেক্ট করুন", "multiSelect": "একাধিক সিলেক্ট করুন",
"moveCanvas": "ক্যানভাস সরান", "moveCanvas": "ক্যানভাস সরান",
@@ -53,14 +49,7 @@
"arrowhead_crowfoot_many": "", "arrowhead_crowfoot_many": "",
"arrowhead_crowfoot_one": "", "arrowhead_crowfoot_one": "",
"arrowhead_crowfoot_one_or_many": "", "arrowhead_crowfoot_one_or_many": "",
"arrowhead_cardinality_one": "",
"arrowhead_cardinality_many": "",
"arrowhead_cardinality_one_or_many": "",
"arrowhead_cardinality_exactly_one": "",
"arrowhead_cardinality_zero_or_one": "",
"arrowhead_cardinality_zero_or_many": "",
"more_options": "", "more_options": "",
"cardinality": "",
"arrowtypes": "", "arrowtypes": "",
"arrowtype_sharp": "", "arrowtype_sharp": "",
"arrowtype_round": "", "arrowtype_round": "",
@@ -182,11 +171,7 @@
"linkToElement": "", "linkToElement": "",
"wrapSelectionInFrame": "", "wrapSelectionInFrame": "",
"tab": "", "tab": "",
"shapeSwitch": "", "shapeSwitch": ""
"preferences": "",
"preferences_toolLock": "",
"arrowBinding": "",
"midpointSnapping": ""
}, },
"elementLink": { "elementLink": {
"title": "", "title": "",
@@ -410,10 +395,6 @@
"errorDialog": { "errorDialog": {
"title": "ত্রুটি" "title": "ত্রুটি"
}, },
"progressDialog": {
"title": "",
"defaultMessage": ""
},
"exportDialog": { "exportDialog": {
"disk_title": "", "disk_title": "",
"disk_details": "", "disk_details": "",
@@ -635,8 +616,7 @@
"syntax": "", "syntax": "",
"preview": "", "preview": "",
"label": "", "label": "",
"inputPlaceholder": "", "inputPlaceholder": ""
"autoFixAvailable": ""
}, },
"ttd": { "ttd": {
"error": "" "error": ""
+2 -22
View File
@@ -3,10 +3,6 @@
"paste": "পেস্ট করুন", "paste": "পেস্ট করুন",
"pasteAsPlaintext": "প্লেইনটেক্সট হিসাবে পেস্ট করুন", "pasteAsPlaintext": "প্লেইনটেক্সট হিসাবে পেস্ট করুন",
"pasteCharts": "চার্ট পেস্ট করুন", "pasteCharts": "চার্ট পেস্ট করুন",
"chartType_bar": "",
"chartType_line": "",
"chartType_radar": "",
"chartType_plaintext": "",
"selectAll": "সবটা সিলেক্ট করুন", "selectAll": "সবটা সিলেক্ট করুন",
"multiSelect": "একাধিক সিলেক্ট করুন", "multiSelect": "একাধিক সিলেক্ট করুন",
"moveCanvas": "ক্যানভাস সরান", "moveCanvas": "ক্যানভাস সরান",
@@ -53,14 +49,7 @@
"arrowhead_crowfoot_many": "", "arrowhead_crowfoot_many": "",
"arrowhead_crowfoot_one": "", "arrowhead_crowfoot_one": "",
"arrowhead_crowfoot_one_or_many": "", "arrowhead_crowfoot_one_or_many": "",
"arrowhead_cardinality_one": "",
"arrowhead_cardinality_many": "",
"arrowhead_cardinality_one_or_many": "",
"arrowhead_cardinality_exactly_one": "",
"arrowhead_cardinality_zero_or_one": "",
"arrowhead_cardinality_zero_or_many": "",
"more_options": "", "more_options": "",
"cardinality": "",
"arrowtypes": "", "arrowtypes": "",
"arrowtype_sharp": "", "arrowtype_sharp": "",
"arrowtype_round": "", "arrowtype_round": "",
@@ -182,11 +171,7 @@
"linkToElement": "", "linkToElement": "",
"wrapSelectionInFrame": "", "wrapSelectionInFrame": "",
"tab": "", "tab": "",
"shapeSwitch": "", "shapeSwitch": ""
"preferences": "",
"preferences_toolLock": "",
"arrowBinding": "",
"midpointSnapping": ""
}, },
"elementLink": { "elementLink": {
"title": "", "title": "",
@@ -410,10 +395,6 @@
"errorDialog": { "errorDialog": {
"title": "ত্রুটি" "title": "ত্রুটি"
}, },
"progressDialog": {
"title": "",
"defaultMessage": ""
},
"exportDialog": { "exportDialog": {
"disk_title": "", "disk_title": "",
"disk_details": "", "disk_details": "",
@@ -635,8 +616,7 @@
"syntax": "", "syntax": "",
"preview": "", "preview": "",
"label": "", "label": "",
"inputPlaceholder": "", "inputPlaceholder": ""
"autoFixAvailable": ""
}, },
"ttd": { "ttd": {
"error": "" "error": ""
+3 -23
View File
@@ -3,10 +3,6 @@
"paste": "Enganxa", "paste": "Enganxa",
"pasteAsPlaintext": "Enganxar com a text pla", "pasteAsPlaintext": "Enganxar com a text pla",
"pasteCharts": "Enganxa els diagrames", "pasteCharts": "Enganxa els diagrames",
"chartType_bar": "",
"chartType_line": "",
"chartType_radar": "",
"chartType_plaintext": "",
"selectAll": "Selecciona-ho tot", "selectAll": "Selecciona-ho tot",
"multiSelect": "Afegeix un element a la selecció", "multiSelect": "Afegeix un element a la selecció",
"moveCanvas": "Mou el llenç", "moveCanvas": "Mou el llenç",
@@ -53,14 +49,7 @@
"arrowhead_crowfoot_many": "Potes de gall (moltes)", "arrowhead_crowfoot_many": "Potes de gall (moltes)",
"arrowhead_crowfoot_one": "Potes de gall (una)", "arrowhead_crowfoot_one": "Potes de gall (una)",
"arrowhead_crowfoot_one_or_many": "Potes de gall (una o moltes)", "arrowhead_crowfoot_one_or_many": "Potes de gall (una o moltes)",
"arrowhead_cardinality_one": "",
"arrowhead_cardinality_many": "",
"arrowhead_cardinality_one_or_many": "",
"arrowhead_cardinality_exactly_one": "",
"arrowhead_cardinality_zero_or_one": "",
"arrowhead_cardinality_zero_or_many": "",
"more_options": "Més opcions", "more_options": "Més opcions",
"cardinality": "",
"arrowtypes": "Tipus de fletxa", "arrowtypes": "Tipus de fletxa",
"arrowtype_sharp": "Fletxa Esmolada", "arrowtype_sharp": "Fletxa Esmolada",
"arrowtype_round": "Fletxa corba", "arrowtype_round": "Fletxa corba",
@@ -182,11 +171,7 @@
"linkToElement": "Enllaç a l'objecte", "linkToElement": "Enllaç a l'objecte",
"wrapSelectionInFrame": "Embolica la selecció en un marc", "wrapSelectionInFrame": "Embolica la selecció en un marc",
"tab": "", "tab": "",
"shapeSwitch": "", "shapeSwitch": ""
"preferences": "",
"preferences_toolLock": "",
"arrowBinding": "",
"midpointSnapping": ""
}, },
"elementLink": { "elementLink": {
"title": "Enllaç a l'objecte", "title": "Enllaç a l'objecte",
@@ -410,10 +395,6 @@
"errorDialog": { "errorDialog": {
"title": "Error" "title": "Error"
}, },
"progressDialog": {
"title": "",
"defaultMessage": ""
},
"exportDialog": { "exportDialog": {
"disk_title": "Desa al disc", "disk_title": "Desa al disc",
"disk_details": "Exporta les dades de l'escena a un fitxer que després podreu importar.", "disk_details": "Exporta les dades de l'escena a un fitxer que després podreu importar.",
@@ -631,12 +612,11 @@
"mermaid": { "mermaid": {
"title": "Mermaid a Excalidraw", "title": "Mermaid a Excalidraw",
"button": "Inseriu", "button": "Inseriu",
"description": "", "description": "Actualment només s'admeten els diagrames <flowchartLink>Flowchart</flowchartLink>, <sequenceLink> Sequence, </sequenceLink> i <classLink> Class </classLink>. Els altres tipus es representaran com a imatge a Excalidraw.",
"syntax": "Sintaxi de Mermaid", "syntax": "Sintaxi de Mermaid",
"preview": "Previsualització", "preview": "Previsualització",
"label": "", "label": "",
"inputPlaceholder": "", "inputPlaceholder": ""
"autoFixAvailable": ""
}, },
"ttd": { "ttd": {
"error": "" "error": ""
+2 -22
View File
@@ -3,10 +3,6 @@
"paste": "Vložit", "paste": "Vložit",
"pasteAsPlaintext": "Vložit jako prostý text", "pasteAsPlaintext": "Vložit jako prostý text",
"pasteCharts": "Vložit grafy", "pasteCharts": "Vložit grafy",
"chartType_bar": "",
"chartType_line": "",
"chartType_radar": "",
"chartType_plaintext": "",
"selectAll": "Vybrat vše", "selectAll": "Vybrat vše",
"multiSelect": "Přidat prvek do výběru", "multiSelect": "Přidat prvek do výběru",
"moveCanvas": "Posunout plátno", "moveCanvas": "Posunout plátno",
@@ -53,14 +49,7 @@
"arrowhead_crowfoot_many": "", "arrowhead_crowfoot_many": "",
"arrowhead_crowfoot_one": "", "arrowhead_crowfoot_one": "",
"arrowhead_crowfoot_one_or_many": "", "arrowhead_crowfoot_one_or_many": "",
"arrowhead_cardinality_one": "",
"arrowhead_cardinality_many": "",
"arrowhead_cardinality_one_or_many": "",
"arrowhead_cardinality_exactly_one": "",
"arrowhead_cardinality_zero_or_one": "",
"arrowhead_cardinality_zero_or_many": "",
"more_options": "", "more_options": "",
"cardinality": "",
"arrowtypes": "Typ šipky", "arrowtypes": "Typ šipky",
"arrowtype_sharp": "Ostrá šipka", "arrowtype_sharp": "Ostrá šipka",
"arrowtype_round": "Zakřivená šipka", "arrowtype_round": "Zakřivená šipka",
@@ -182,11 +171,7 @@
"linkToElement": "Odkaz na objekt", "linkToElement": "Odkaz na objekt",
"wrapSelectionInFrame": "", "wrapSelectionInFrame": "",
"tab": "", "tab": "",
"shapeSwitch": "", "shapeSwitch": ""
"preferences": "",
"preferences_toolLock": "",
"arrowBinding": "",
"midpointSnapping": ""
}, },
"elementLink": { "elementLink": {
"title": "Odkaz na objekt", "title": "Odkaz na objekt",
@@ -410,10 +395,6 @@
"errorDialog": { "errorDialog": {
"title": "Chyba" "title": "Chyba"
}, },
"progressDialog": {
"title": "",
"defaultMessage": ""
},
"exportDialog": { "exportDialog": {
"disk_title": "Uložit na disk", "disk_title": "Uložit na disk",
"disk_details": "Exportovat data scény do souboru, ze kterého můžete importovat později.", "disk_details": "Exportovat data scény do souboru, ze kterého můžete importovat později.",
@@ -635,8 +616,7 @@
"syntax": "Mermaid syntaxe", "syntax": "Mermaid syntaxe",
"preview": "Náhled", "preview": "Náhled",
"label": "", "label": "",
"inputPlaceholder": "", "inputPlaceholder": ""
"autoFixAvailable": ""
}, },
"ttd": { "ttd": {
"error": "" "error": ""
+2 -22
View File
@@ -3,10 +3,6 @@
"paste": "Indsæt", "paste": "Indsæt",
"pasteAsPlaintext": "Indsæt som klartekst", "pasteAsPlaintext": "Indsæt som klartekst",
"pasteCharts": "Indsæt diagrammer", "pasteCharts": "Indsæt diagrammer",
"chartType_bar": "",
"chartType_line": "",
"chartType_radar": "",
"chartType_plaintext": "",
"selectAll": "Marker alle", "selectAll": "Marker alle",
"multiSelect": "Tilføj element til markering", "multiSelect": "Tilføj element til markering",
"moveCanvas": "Flyt lærred", "moveCanvas": "Flyt lærred",
@@ -53,14 +49,7 @@
"arrowhead_crowfoot_many": "Kragefod (mange)", "arrowhead_crowfoot_many": "Kragefod (mange)",
"arrowhead_crowfoot_one": "Kragefod (én)", "arrowhead_crowfoot_one": "Kragefod (én)",
"arrowhead_crowfoot_one_or_many": "Kragefod (én eller mange)", "arrowhead_crowfoot_one_or_many": "Kragefod (én eller mange)",
"arrowhead_cardinality_one": "",
"arrowhead_cardinality_many": "",
"arrowhead_cardinality_one_or_many": "",
"arrowhead_cardinality_exactly_one": "",
"arrowhead_cardinality_zero_or_one": "",
"arrowhead_cardinality_zero_or_many": "",
"more_options": "Flere muligheder", "more_options": "Flere muligheder",
"cardinality": "",
"arrowtypes": "Pile type", "arrowtypes": "Pile type",
"arrowtype_sharp": "Skarp pil", "arrowtype_sharp": "Skarp pil",
"arrowtype_round": "Buet pil", "arrowtype_round": "Buet pil",
@@ -182,11 +171,7 @@
"linkToElement": "", "linkToElement": "",
"wrapSelectionInFrame": "", "wrapSelectionInFrame": "",
"tab": "", "tab": "",
"shapeSwitch": "", "shapeSwitch": ""
"preferences": "",
"preferences_toolLock": "",
"arrowBinding": "",
"midpointSnapping": ""
}, },
"elementLink": { "elementLink": {
"title": "", "title": "",
@@ -410,10 +395,6 @@
"errorDialog": { "errorDialog": {
"title": "Fejl" "title": "Fejl"
}, },
"progressDialog": {
"title": "",
"defaultMessage": ""
},
"exportDialog": { "exportDialog": {
"disk_title": "Gem til disk", "disk_title": "Gem til disk",
"disk_details": "", "disk_details": "",
@@ -635,8 +616,7 @@
"syntax": "", "syntax": "",
"preview": "", "preview": "",
"label": "", "label": "",
"inputPlaceholder": "", "inputPlaceholder": ""
"autoFixAvailable": ""
}, },
"ttd": { "ttd": {
"error": "" "error": ""
+3 -23
View File
@@ -3,10 +3,6 @@
"paste": "Einfügen", "paste": "Einfügen",
"pasteAsPlaintext": "Als unformatierten Text einfügen", "pasteAsPlaintext": "Als unformatierten Text einfügen",
"pasteCharts": "Diagramme einfügen", "pasteCharts": "Diagramme einfügen",
"chartType_bar": "",
"chartType_line": "",
"chartType_radar": "",
"chartType_plaintext": "",
"selectAll": "Alle auswählen", "selectAll": "Alle auswählen",
"multiSelect": "Element zur Auswahl hinzufügen", "multiSelect": "Element zur Auswahl hinzufügen",
"moveCanvas": "Leinwand verschieben", "moveCanvas": "Leinwand verschieben",
@@ -53,14 +49,7 @@
"arrowhead_crowfoot_many": "Krähenfuß (viele)", "arrowhead_crowfoot_many": "Krähenfuß (viele)",
"arrowhead_crowfoot_one": "Krähenfuß (einer)", "arrowhead_crowfoot_one": "Krähenfuß (einer)",
"arrowhead_crowfoot_one_or_many": "Krähenfuß (einer oder viele)", "arrowhead_crowfoot_one_or_many": "Krähenfuß (einer oder viele)",
"arrowhead_cardinality_one": "",
"arrowhead_cardinality_many": "",
"arrowhead_cardinality_one_or_many": "",
"arrowhead_cardinality_exactly_one": "",
"arrowhead_cardinality_zero_or_one": "",
"arrowhead_cardinality_zero_or_many": "",
"more_options": "Weitere Optionen", "more_options": "Weitere Optionen",
"cardinality": "",
"arrowtypes": "Pfeiltyp", "arrowtypes": "Pfeiltyp",
"arrowtype_sharp": "Scharfer Pfeil", "arrowtype_sharp": "Scharfer Pfeil",
"arrowtype_round": "Gebogener Pfeil", "arrowtype_round": "Gebogener Pfeil",
@@ -182,11 +171,7 @@
"linkToElement": "Link zum Objekt", "linkToElement": "Link zum Objekt",
"wrapSelectionInFrame": "Auswahl in Rahmen einbetten", "wrapSelectionInFrame": "Auswahl in Rahmen einbetten",
"tab": "", "tab": "",
"shapeSwitch": "", "shapeSwitch": ""
"preferences": "",
"preferences_toolLock": "",
"arrowBinding": "",
"midpointSnapping": ""
}, },
"elementLink": { "elementLink": {
"title": "Link zum Objekt", "title": "Link zum Objekt",
@@ -410,10 +395,6 @@
"errorDialog": { "errorDialog": {
"title": "Fehler" "title": "Fehler"
}, },
"progressDialog": {
"title": "",
"defaultMessage": ""
},
"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.",
@@ -631,12 +612,11 @@
"mermaid": { "mermaid": {
"title": "Mermaid zu Excalidraw", "title": "Mermaid zu Excalidraw",
"button": "Einfügen", "button": "Einfügen",
"description": "", "description": "Derzeit werden nur <flowchartLink>Flussdiagramme</flowchartLink>, <sequenceLink>Sequenzdiagramme</sequenceLink> und <classLink>Klassendiagramme</classLink> unterstützt. Die anderen Typen werden als Bild in Excalidraw dargestellt.",
"syntax": "Mermaid-Syntax", "syntax": "Mermaid-Syntax",
"preview": "Vorschau", "preview": "Vorschau",
"label": "", "label": "",
"inputPlaceholder": "", "inputPlaceholder": ""
"autoFixAvailable": ""
}, },
"ttd": { "ttd": {
"error": "" "error": ""
+3 -23
View File
@@ -3,10 +3,6 @@
"paste": "Einfügen", "paste": "Einfügen",
"pasteAsPlaintext": "Als unformatierten Text einfügen", "pasteAsPlaintext": "Als unformatierten Text einfügen",
"pasteCharts": "Diagramme einfügen", "pasteCharts": "Diagramme einfügen",
"chartType_bar": "",
"chartType_line": "",
"chartType_radar": "",
"chartType_plaintext": "",
"selectAll": "Alle auswählen", "selectAll": "Alle auswählen",
"multiSelect": "Element zur Auswahl hinzufügen", "multiSelect": "Element zur Auswahl hinzufügen",
"moveCanvas": "Leinwand verschieben", "moveCanvas": "Leinwand verschieben",
@@ -53,14 +49,7 @@
"arrowhead_crowfoot_many": "Krähenfuß (viele)", "arrowhead_crowfoot_many": "Krähenfuß (viele)",
"arrowhead_crowfoot_one": "Krähenfuß (einer)", "arrowhead_crowfoot_one": "Krähenfuß (einer)",
"arrowhead_crowfoot_one_or_many": "Krähenfuß (einer oder viele)", "arrowhead_crowfoot_one_or_many": "Krähenfuß (einer oder viele)",
"arrowhead_cardinality_one": "",
"arrowhead_cardinality_many": "",
"arrowhead_cardinality_one_or_many": "",
"arrowhead_cardinality_exactly_one": "",
"arrowhead_cardinality_zero_or_one": "",
"arrowhead_cardinality_zero_or_many": "",
"more_options": "Weitere Optionen", "more_options": "Weitere Optionen",
"cardinality": "",
"arrowtypes": "Pfeiltyp", "arrowtypes": "Pfeiltyp",
"arrowtype_sharp": "Scharfer Pfeil", "arrowtype_sharp": "Scharfer Pfeil",
"arrowtype_round": "Gebogener Pfeil", "arrowtype_round": "Gebogener Pfeil",
@@ -182,11 +171,7 @@
"linkToElement": "Link zum Objekt", "linkToElement": "Link zum Objekt",
"wrapSelectionInFrame": "Auswahl in Rahmen einbetten", "wrapSelectionInFrame": "Auswahl in Rahmen einbetten",
"tab": "", "tab": "",
"shapeSwitch": "", "shapeSwitch": ""
"preferences": "",
"preferences_toolLock": "",
"arrowBinding": "",
"midpointSnapping": ""
}, },
"elementLink": { "elementLink": {
"title": "Link zum Objekt", "title": "Link zum Objekt",
@@ -410,10 +395,6 @@
"errorDialog": { "errorDialog": {
"title": "Fehler" "title": "Fehler"
}, },
"progressDialog": {
"title": "",
"defaultMessage": ""
},
"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.",
@@ -631,12 +612,11 @@
"mermaid": { "mermaid": {
"title": "Mermaid zu Excalidraw", "title": "Mermaid zu Excalidraw",
"button": "Einfügen", "button": "Einfügen",
"description": "", "description": "Derzeit werden nur <flowchartLink>Flussdiagramme</flowchartLink>, <sequenceLink>Sequenzdiagramme</sequenceLink> und <classLink>Klassendiagramme</classLink> unterstützt. Die anderen Typen werden als Bild in Excalidraw dargestellt.",
"syntax": "Mermaid-Syntax", "syntax": "Mermaid-Syntax",
"preview": "Vorschau", "preview": "Vorschau",
"label": "", "label": "",
"inputPlaceholder": "", "inputPlaceholder": ""
"autoFixAvailable": ""
}, },
"ttd": { "ttd": {
"error": "" "error": ""
+3 -23
View File
@@ -3,10 +3,6 @@
"paste": "Επικόλληση", "paste": "Επικόλληση",
"pasteAsPlaintext": "Επικόλληση ως απλό κείμενο", "pasteAsPlaintext": "Επικόλληση ως απλό κείμενο",
"pasteCharts": "Επικόλληση γραφημάτων", "pasteCharts": "Επικόλληση γραφημάτων",
"chartType_bar": "",
"chartType_line": "",
"chartType_radar": "",
"chartType_plaintext": "",
"selectAll": "Επιλογή όλων", "selectAll": "Επιλογή όλων",
"multiSelect": "Προσθέστε το στοιχείο στην επιλογή", "multiSelect": "Προσθέστε το στοιχείο στην επιλογή",
"moveCanvas": "Μετακίνηση καμβά", "moveCanvas": "Μετακίνηση καμβά",
@@ -53,14 +49,7 @@
"arrowhead_crowfoot_many": "", "arrowhead_crowfoot_many": "",
"arrowhead_crowfoot_one": "", "arrowhead_crowfoot_one": "",
"arrowhead_crowfoot_one_or_many": "", "arrowhead_crowfoot_one_or_many": "",
"arrowhead_cardinality_one": "",
"arrowhead_cardinality_many": "",
"arrowhead_cardinality_one_or_many": "",
"arrowhead_cardinality_exactly_one": "",
"arrowhead_cardinality_zero_or_one": "",
"arrowhead_cardinality_zero_or_many": "",
"more_options": "", "more_options": "",
"cardinality": "",
"arrowtypes": "Τύπος βέλους", "arrowtypes": "Τύπος βέλους",
"arrowtype_sharp": "Αιχμηρό βέλος", "arrowtype_sharp": "Αιχμηρό βέλος",
"arrowtype_round": "Κυρτό βέλος", "arrowtype_round": "Κυρτό βέλος",
@@ -182,11 +171,7 @@
"linkToElement": "", "linkToElement": "",
"wrapSelectionInFrame": "", "wrapSelectionInFrame": "",
"tab": "", "tab": "",
"shapeSwitch": "", "shapeSwitch": ""
"preferences": "",
"preferences_toolLock": "",
"arrowBinding": "",
"midpointSnapping": ""
}, },
"elementLink": { "elementLink": {
"title": "", "title": "",
@@ -410,10 +395,6 @@
"errorDialog": { "errorDialog": {
"title": "Σφάλμα" "title": "Σφάλμα"
}, },
"progressDialog": {
"title": "",
"defaultMessage": ""
},
"exportDialog": { "exportDialog": {
"disk_title": "Αποθήκευση στο δίσκο", "disk_title": "Αποθήκευση στο δίσκο",
"disk_details": "Εξαγωγή δεδομένων σκηνής σε ένα αρχείο από το οποίο μπορείτε να εισάγετε αργότερα.", "disk_details": "Εξαγωγή δεδομένων σκηνής σε ένα αρχείο από το οποίο μπορείτε να εισάγετε αργότερα.",
@@ -631,12 +612,11 @@
"mermaid": { "mermaid": {
"title": "Mermaid σε Excalidraw", "title": "Mermaid σε Excalidraw",
"button": "Εισαγωγή", "button": "Εισαγωγή",
"description": "", "description": "Επί του παρόντος υποστηρίζονται μόνο Διαγράμματα <flowchartLink>Ροής</flowchartLink>,<sequenceLink> Ακολουθίας, </sequenceLink> και <classLink>Κλάσεων</classLink>. Οι άλλοι τύποι θα αποδοθούν ως εικόνα στο Excalidraw.",
"syntax": "Σύνταξη Mermaid", "syntax": "Σύνταξη Mermaid",
"preview": "Προεπισκόπηση", "preview": "Προεπισκόπηση",
"label": "", "label": "",
"inputPlaceholder": "", "inputPlaceholder": ""
"autoFixAvailable": ""
}, },
"ttd": { "ttd": {
"error": "" "error": ""
+1 -7
View File
@@ -3,10 +3,6 @@
"paste": "Paste", "paste": "Paste",
"pasteAsPlaintext": "Paste as plaintext", "pasteAsPlaintext": "Paste as plaintext",
"pasteCharts": "Paste charts", "pasteCharts": "Paste charts",
"chartType_bar": "Bar chart",
"chartType_line": "Line chart",
"chartType_radar": "Radar chart",
"chartType_plaintext": "Plain text",
"selectAll": "Select all", "selectAll": "Select all",
"multiSelect": "Add element to selection", "multiSelect": "Add element to selection",
"moveCanvas": "Move canvas", "moveCanvas": "Move canvas",
@@ -177,9 +173,7 @@
"tab": "Tab", "tab": "Tab",
"shapeSwitch": "Switch shape", "shapeSwitch": "Switch shape",
"preferences": "Preferences", "preferences": "Preferences",
"preferences_toolLock": "Tool lock", "preferences_toolLock": "Tool lock"
"arrowBinding": "Arrow binding",
"midpointSnapping": "Snap to midpoints"
}, },
"elementLink": { "elementLink": {
"title": "Link to object", "title": "Link to object",
+3 -23
View File
@@ -3,10 +3,6 @@
"paste": "Pegar", "paste": "Pegar",
"pasteAsPlaintext": "Pegar como texto sin formato", "pasteAsPlaintext": "Pegar como texto sin formato",
"pasteCharts": "Pegar gráficos", "pasteCharts": "Pegar gráficos",
"chartType_bar": "",
"chartType_line": "",
"chartType_radar": "",
"chartType_plaintext": "",
"selectAll": "Seleccionar todo", "selectAll": "Seleccionar todo",
"multiSelect": "Añadir elemento a la selección", "multiSelect": "Añadir elemento a la selección",
"moveCanvas": "Mover el lienzo", "moveCanvas": "Mover el lienzo",
@@ -53,14 +49,7 @@
"arrowhead_crowfoot_many": "Pie de la corona (varios)", "arrowhead_crowfoot_many": "Pie de la corona (varios)",
"arrowhead_crowfoot_one": "Pie de la corona (uno)", "arrowhead_crowfoot_one": "Pie de la corona (uno)",
"arrowhead_crowfoot_one_or_many": "Pie de la corona (uno o varios)", "arrowhead_crowfoot_one_or_many": "Pie de la corona (uno o varios)",
"arrowhead_cardinality_one": "",
"arrowhead_cardinality_many": "",
"arrowhead_cardinality_one_or_many": "",
"arrowhead_cardinality_exactly_one": "",
"arrowhead_cardinality_zero_or_one": "",
"arrowhead_cardinality_zero_or_many": "",
"more_options": "Más opciones", "more_options": "Más opciones",
"cardinality": "",
"arrowtypes": "Tipo de flecha", "arrowtypes": "Tipo de flecha",
"arrowtype_sharp": "Flecha Afilada", "arrowtype_sharp": "Flecha Afilada",
"arrowtype_round": "Flecha Curva", "arrowtype_round": "Flecha Curva",
@@ -182,11 +171,7 @@
"linkToElement": "Enlace al objeto", "linkToElement": "Enlace al objeto",
"wrapSelectionInFrame": "Ajustar la selección en el marco", "wrapSelectionInFrame": "Ajustar la selección en el marco",
"tab": "", "tab": "",
"shapeSwitch": "", "shapeSwitch": ""
"preferences": "",
"preferences_toolLock": "",
"arrowBinding": "",
"midpointSnapping": ""
}, },
"elementLink": { "elementLink": {
"title": "Enlace al objeto", "title": "Enlace al objeto",
@@ -410,10 +395,6 @@
"errorDialog": { "errorDialog": {
"title": "Error" "title": "Error"
}, },
"progressDialog": {
"title": "",
"defaultMessage": ""
},
"exportDialog": { "exportDialog": {
"disk_title": "Guardar en disco", "disk_title": "Guardar en disco",
"disk_details": "Exportar los datos de la escena a un archivo desde el cual pueda importar más tarde.", "disk_details": "Exportar los datos de la escena a un archivo desde el cual pueda importar más tarde.",
@@ -631,12 +612,11 @@
"mermaid": { "mermaid": {
"title": "Mermaid a Excalidraw", "title": "Mermaid a Excalidraw",
"button": "Insertar", "button": "Insertar",
"description": "", "description": "Actualmente sólo estos tipos de <flowchartLink>diagrama de flujo</flowchartLink>,<sequenceLink> Secuencia, </sequenceLink> y <classLink>Clase </classLink> son soportados. Los otros tipos de diagramas se renderizarán como imagen en Excalidraw.",
"syntax": "Sintaxis Mermaid", "syntax": "Sintaxis Mermaid",
"preview": "Vista previa", "preview": "Vista previa",
"label": "", "label": "",
"inputPlaceholder": "", "inputPlaceholder": ""
"autoFixAvailable": ""
}, },
"ttd": { "ttd": {
"error": "" "error": ""
+3 -23
View File
@@ -3,10 +3,6 @@
"paste": "Itsatsi", "paste": "Itsatsi",
"pasteAsPlaintext": "Itsatsi testu arrunt gisa", "pasteAsPlaintext": "Itsatsi testu arrunt gisa",
"pasteCharts": "Itsatsi grafikoak", "pasteCharts": "Itsatsi grafikoak",
"chartType_bar": "",
"chartType_line": "",
"chartType_radar": "",
"chartType_plaintext": "",
"selectAll": "Hautatu dena", "selectAll": "Hautatu dena",
"multiSelect": "Gehitu elementua hautapenera", "multiSelect": "Gehitu elementua hautapenera",
"moveCanvas": "Mugitu oihala", "moveCanvas": "Mugitu oihala",
@@ -53,14 +49,7 @@
"arrowhead_crowfoot_many": "", "arrowhead_crowfoot_many": "",
"arrowhead_crowfoot_one": "", "arrowhead_crowfoot_one": "",
"arrowhead_crowfoot_one_or_many": "", "arrowhead_crowfoot_one_or_many": "",
"arrowhead_cardinality_one": "",
"arrowhead_cardinality_many": "",
"arrowhead_cardinality_one_or_many": "",
"arrowhead_cardinality_exactly_one": "",
"arrowhead_cardinality_zero_or_one": "",
"arrowhead_cardinality_zero_or_many": "",
"more_options": "", "more_options": "",
"cardinality": "",
"arrowtypes": "", "arrowtypes": "",
"arrowtype_sharp": "", "arrowtype_sharp": "",
"arrowtype_round": "", "arrowtype_round": "",
@@ -182,11 +171,7 @@
"linkToElement": "", "linkToElement": "",
"wrapSelectionInFrame": "", "wrapSelectionInFrame": "",
"tab": "", "tab": "",
"shapeSwitch": "", "shapeSwitch": ""
"preferences": "",
"preferences_toolLock": "",
"arrowBinding": "",
"midpointSnapping": ""
}, },
"elementLink": { "elementLink": {
"title": "", "title": "",
@@ -410,10 +395,6 @@
"errorDialog": { "errorDialog": {
"title": "Errorea" "title": "Errorea"
}, },
"progressDialog": {
"title": "",
"defaultMessage": ""
},
"exportDialog": { "exportDialog": {
"disk_title": "Gorde diskoan", "disk_title": "Gorde diskoan",
"disk_details": "Esportatu eszenaren datuak geroago inportatu ahal izango duzun fitxategi batan.", "disk_details": "Esportatu eszenaren datuak geroago inportatu ahal izango duzun fitxategi batan.",
@@ -631,12 +612,11 @@
"mermaid": { "mermaid": {
"title": "Mermaid-etik Excalidraw-ra", "title": "Mermaid-etik Excalidraw-ra",
"button": "Txertatu", "button": "Txertatu",
"description": "", "description": "Momentu honetan <flowchartLink>Flowchart</flowchartLink>, <sequenceLink> Sequence, </sequenceLink> eta <classLink>Class </classLink>Diagramak onartzen dira. Beste motak irudi gisa errendatuko dira Excalidrawn.",
"syntax": "Mermaid sintaxia", "syntax": "Mermaid sintaxia",
"preview": "Aurrebista", "preview": "Aurrebista",
"label": "", "label": "",
"inputPlaceholder": "", "inputPlaceholder": ""
"autoFixAvailable": ""
}, },
"ttd": { "ttd": {
"error": "" "error": ""
+11 -31
View File
@@ -3,10 +3,6 @@
"paste": "جایگذاری", "paste": "جایگذاری",
"pasteAsPlaintext": "جایگذاری به عنوان متن ساده", "pasteAsPlaintext": "جایگذاری به عنوان متن ساده",
"pasteCharts": "جایگذاری نمودارها", "pasteCharts": "جایگذاری نمودارها",
"chartType_bar": "",
"chartType_line": "",
"chartType_radar": "",
"chartType_plaintext": "",
"selectAll": "انتخاب همه", "selectAll": "انتخاب همه",
"multiSelect": "یک ایتم به انتخاب شده ها اضافه کنید", "multiSelect": "یک ایتم به انتخاب شده ها اضافه کنید",
"moveCanvas": "جابجایی بوم", "moveCanvas": "جابجایی بوم",
@@ -53,14 +49,7 @@
"arrowhead_crowfoot_many": "پای کلاغی (بسیار)", "arrowhead_crowfoot_many": "پای کلاغی (بسیار)",
"arrowhead_crowfoot_one": "پای کلاغی (یک)", "arrowhead_crowfoot_one": "پای کلاغی (یک)",
"arrowhead_crowfoot_one_or_many": "پای کلاغی (یک یا بسیار)", "arrowhead_crowfoot_one_or_many": "پای کلاغی (یک یا بسیار)",
"arrowhead_cardinality_one": "",
"arrowhead_cardinality_many": "",
"arrowhead_cardinality_one_or_many": "",
"arrowhead_cardinality_exactly_one": "",
"arrowhead_cardinality_zero_or_one": "",
"arrowhead_cardinality_zero_or_many": "",
"more_options": "امکانات بیشتر", "more_options": "امکانات بیشتر",
"cardinality": "",
"arrowtypes": "نوع پیکان", "arrowtypes": "نوع پیکان",
"arrowtype_sharp": "پیکان تیز", "arrowtype_sharp": "پیکان تیز",
"arrowtype_round": "پیکان منحنی", "arrowtype_round": "پیکان منحنی",
@@ -182,11 +171,7 @@
"linkToElement": "لینک به آیتم", "linkToElement": "لینک به آیتم",
"wrapSelectionInFrame": "انتخاب را در قاب قرار دهید", "wrapSelectionInFrame": "انتخاب را در قاب قرار دهید",
"tab": "", "tab": "",
"shapeSwitch": "", "shapeSwitch": ""
"preferences": "",
"preferences_toolLock": "",
"arrowBinding": "",
"midpointSnapping": ""
}, },
"elementLink": { "elementLink": {
"title": "لینک به آیتم", "title": "لینک به آیتم",
@@ -211,7 +196,7 @@
"multipleResults": "نتایج", "multipleResults": "نتایج",
"placeholder": "جستجوی متن در بوم...", "placeholder": "جستجوی متن در بوم...",
"frames": "", "frames": "",
"texts": "متن" "texts": ""
}, },
"buttons": { "buttons": {
"clearReset": "پاکسازی بوم نقاشی", "clearReset": "پاکسازی بوم نقاشی",
@@ -410,10 +395,6 @@
"errorDialog": { "errorDialog": {
"title": "خطا" "title": "خطا"
}, },
"progressDialog": {
"title": "",
"defaultMessage": ""
},
"exportDialog": { "exportDialog": {
"disk_title": "ذخیره در دیسک", "disk_title": "ذخیره در دیسک",
"disk_details": "داده های صحنه را به فایلی که بعداً می توانید از آن وارد کنید صادر کنید.", "disk_details": "داده های صحنه را به فایلی که بعداً می توانید از آن وارد کنید صادر کنید.",
@@ -590,7 +571,7 @@
} }
}, },
"colorPicker": { "colorPicker": {
"color": "رنگ", "color": "",
"mostUsedCustomColors": "رنگ های به‌تازگی به‌کار گرفته شده", "mostUsedCustomColors": "رنگ های به‌تازگی به‌کار گرفته شده",
"colors": "رنگ‌ها", "colors": "رنگ‌ها",
"shades": "جلوه‌ها", "shades": "جلوه‌ها",
@@ -631,15 +612,14 @@
"mermaid": { "mermaid": {
"title": "مرمید به excalidraw", "title": "مرمید به excalidraw",
"button": "درج", "button": "درج",
"description": "", "description": "فعلا فقط <flowchartLink> فلوچارت </flowchartLink> ، <sequenceLink> توالی </sequenceLink> و <classLink> کلاس </classLink> نمودارها پشتیبانی می شوند. انواع دیگر به صورت تصویر در Excalidraw ارائه خواهند شد.",
"syntax": "مرمید syntax", "syntax": "مرمید syntax",
"preview": "پیشنمایش", "preview": "پیشنمایش",
"label": "", "label": "",
"inputPlaceholder": "", "inputPlaceholder": ""
"autoFixAvailable": ""
}, },
"ttd": { "ttd": {
"error": "خطا!" "error": ""
}, },
"chat": { "chat": {
"inputPlaceholder": "", "inputPlaceholder": "",
@@ -647,8 +627,8 @@
"generating": "", "generating": "",
"rateLimitRemaining": "", "rateLimitRemaining": "",
"role": { "role": {
"user": "شما", "user": "",
"assistant": "دستیار هوش مصنوعی", "assistant": "",
"system": "" "system": ""
}, },
"aiBeta": "", "aiBeta": "",
@@ -727,9 +707,9 @@
"alt": "", "alt": "",
"escape": "", "escape": "",
"enter": "", "enter": "",
"shift": "Shift", "shift": "",
"spacebar": "فاصله", "spacebar": "",
"delete": "حذف", "delete": "",
"mmb": "" "mmb": ""
} }
} }
+2 -22
View File
@@ -3,10 +3,6 @@
"paste": "Liitä", "paste": "Liitä",
"pasteAsPlaintext": "Liitä pelkkänä tekstinä", "pasteAsPlaintext": "Liitä pelkkänä tekstinä",
"pasteCharts": "Liitä kaaviot", "pasteCharts": "Liitä kaaviot",
"chartType_bar": "",
"chartType_line": "",
"chartType_radar": "",
"chartType_plaintext": "",
"selectAll": "Valitse kaikki", "selectAll": "Valitse kaikki",
"multiSelect": "Lisää kohde valintaan", "multiSelect": "Lisää kohde valintaan",
"moveCanvas": "Siirrä piirtoaluetta", "moveCanvas": "Siirrä piirtoaluetta",
@@ -53,14 +49,7 @@
"arrowhead_crowfoot_many": "", "arrowhead_crowfoot_many": "",
"arrowhead_crowfoot_one": "", "arrowhead_crowfoot_one": "",
"arrowhead_crowfoot_one_or_many": "", "arrowhead_crowfoot_one_or_many": "",
"arrowhead_cardinality_one": "",
"arrowhead_cardinality_many": "",
"arrowhead_cardinality_one_or_many": "",
"arrowhead_cardinality_exactly_one": "",
"arrowhead_cardinality_zero_or_one": "",
"arrowhead_cardinality_zero_or_many": "",
"more_options": "", "more_options": "",
"cardinality": "",
"arrowtypes": "", "arrowtypes": "",
"arrowtype_sharp": "", "arrowtype_sharp": "",
"arrowtype_round": "", "arrowtype_round": "",
@@ -182,11 +171,7 @@
"linkToElement": "", "linkToElement": "",
"wrapSelectionInFrame": "", "wrapSelectionInFrame": "",
"tab": "", "tab": "",
"shapeSwitch": "", "shapeSwitch": ""
"preferences": "",
"preferences_toolLock": "",
"arrowBinding": "",
"midpointSnapping": ""
}, },
"elementLink": { "elementLink": {
"title": "", "title": "",
@@ -410,10 +395,6 @@
"errorDialog": { "errorDialog": {
"title": "Virhe" "title": "Virhe"
}, },
"progressDialog": {
"title": "",
"defaultMessage": ""
},
"exportDialog": { "exportDialog": {
"disk_title": "Tallenna levylle", "disk_title": "Tallenna levylle",
"disk_details": "Vie työn tiedot tiedostoon, josta sen voi tuoda myöhemmin.", "disk_details": "Vie työn tiedot tiedostoon, josta sen voi tuoda myöhemmin.",
@@ -635,8 +616,7 @@
"syntax": "", "syntax": "",
"preview": "Esikatsele", "preview": "Esikatsele",
"label": "", "label": "",
"inputPlaceholder": "", "inputPlaceholder": ""
"autoFixAvailable": ""
}, },
"ttd": { "ttd": {
"error": "" "error": ""
+40 -60
View File
@@ -3,10 +3,6 @@
"paste": "Coller", "paste": "Coller",
"pasteAsPlaintext": "Coller comme texte brut", "pasteAsPlaintext": "Coller comme texte brut",
"pasteCharts": "Coller les graphiques", "pasteCharts": "Coller les graphiques",
"chartType_bar": "Graphique à barres",
"chartType_line": "Courbes",
"chartType_radar": "Diagramme en radar",
"chartType_plaintext": "Texte brut",
"selectAll": "Tout sélectionner", "selectAll": "Tout sélectionner",
"multiSelect": "Ajouter l'élément à la sélection", "multiSelect": "Ajouter l'élément à la sélection",
"moveCanvas": "Déplacer le canevas", "moveCanvas": "Déplacer le canevas",
@@ -53,14 +49,7 @@
"arrowhead_crowfoot_many": "", "arrowhead_crowfoot_many": "",
"arrowhead_crowfoot_one": "Pied de Corde (un)", "arrowhead_crowfoot_one": "Pied de Corde (un)",
"arrowhead_crowfoot_one_or_many": "Pied du corbeau (un ou plusieurs)", "arrowhead_crowfoot_one_or_many": "Pied du corbeau (un ou plusieurs)",
"arrowhead_cardinality_one": "",
"arrowhead_cardinality_many": "",
"arrowhead_cardinality_one_or_many": "",
"arrowhead_cardinality_exactly_one": "",
"arrowhead_cardinality_zero_or_one": "",
"arrowhead_cardinality_zero_or_many": "",
"more_options": "Plus d'options", "more_options": "Plus d'options",
"cardinality": "",
"arrowtypes": "Type de flèche", "arrowtypes": "Type de flèche",
"arrowtype_sharp": "Flèche pointue", "arrowtype_sharp": "Flèche pointue",
"arrowtype_round": "Flèche incurvée", "arrowtype_round": "Flèche incurvée",
@@ -182,11 +171,7 @@
"linkToElement": "Lien vers un objet", "linkToElement": "Lien vers un objet",
"wrapSelectionInFrame": "Mettre la sélection dans un cadre", "wrapSelectionInFrame": "Mettre la sélection dans un cadre",
"tab": "Onglet", "tab": "Onglet",
"shapeSwitch": "Changer de forme", "shapeSwitch": "Changer de forme"
"preferences": "Préférences",
"preferences_toolLock": "Verrouillage de l'outil",
"arrowBinding": "Liaison de flèches",
"midpointSnapping": "S'accrocher aux points intermédiaires"
}, },
"elementLink": { "elementLink": {
"title": "Lien vers un objet", "title": "Lien vers un objet",
@@ -410,10 +395,6 @@
"errorDialog": { "errorDialog": {
"title": "Erreur" "title": "Erreur"
}, },
"progressDialog": {
"title": "",
"defaultMessage": ""
},
"exportDialog": { "exportDialog": {
"disk_title": "Enregistrer sur le disque", "disk_title": "Enregistrer sur le disque",
"disk_details": "Exporter les données de la scène comme un fichier que vous pourrez importer ultérieurement.", "disk_details": "Exporter les données de la scène comme un fichier que vous pourrez importer ultérieurement.",
@@ -576,9 +557,9 @@
}, },
"welcomeScreen": { "welcomeScreen": {
"app": { "app": {
"center_heading": "Vos dessins sont enregistrés dans le stockage de votre navigateur.", "center_heading": "",
"center_heading_line2": "Le stockage du navigateur peut être effacé de manière inattendue.", "center_heading_line2": "",
"center_heading_line3": "Enregistrez régulièrement votre travail dans un fichier pour éviter de le perdre.", "center_heading_line3": "",
"center_heading_plus": "Vouliez-vous plutôt aller à Excalidraw+ à la place ?", "center_heading_plus": "Vouliez-vous plutôt aller à Excalidraw+ à la place ?",
"menuHint": "Exportation, préférences, langues, ..." "menuHint": "Exportation, préférences, langues, ..."
}, },
@@ -631,58 +612,57 @@
"mermaid": { "mermaid": {
"title": "De Mermaid à Excalidraw", "title": "De Mermaid à Excalidraw",
"button": "Insérer", "button": "Insérer",
"description": "", "description": "Actuellement, seuls les diagrammes <flowchartLink>Flowchart</flowchartLink>,<sequenceLink> Sequence, </sequenceLink> et <classLink>de classe </classLink>sont pris en charge. Les autres types seront rendus en tant qu'image dans Excalidraw.",
"syntax": "Syntaxe Mermaid", "syntax": "Syntaxe Mermaid",
"preview": "Prévisualisation", "preview": "Prévisualisation",
"label": "Mermaid", "label": "",
"inputPlaceholder": "Écrivez la définition du diagramme de Mermaid ici...", "inputPlaceholder": ""
"autoFixAvailable": "Correction automatique disponible"
}, },
"ttd": { "ttd": {
"error": "Erreur!" "error": ""
}, },
"chat": { "chat": {
"inputPlaceholder": "Commencez à taper votre idée de diagramme ici... ({{shortcut}} pour une nouvelle ligne)", "inputPlaceholder": "",
"inputPlaceholderWithMessages": "Continuer à affiner votre diagramme...", "inputPlaceholderWithMessages": "",
"generating": "Génération...", "generating": "",
"rateLimitRemaining": "{{count}} demandes restantes aujourd'hui", "rateLimitRemaining": "",
"role": { "role": {
"user": "Vous", "user": "",
"assistant": "Assistant IA", "assistant": "",
"system": "Système" "system": ""
}, },
"aiBeta": "Bêta IA", "aiBeta": "",
"label": "Chat", "label": "",
"menu": "Menu", "menu": "",
"newChat": "Nouveau chat", "newChat": "",
"deleteChat": "Supprimer le chat", "deleteChat": "",
"deleteMessage": "Supprimer le message", "deleteMessage": "",
"viewAsMermaid": "Voir en tant que Mermaid", "viewAsMermaid": "",
"placeholder": { "placeholder": {
"title": "Créons votre diagramme", "title": "",
"description": "Décrivez le diagramme que vous voulez créer, et nous le générerons pour vous.", "description": "",
"hint": "" "hint": ""
}, },
"preview": "Prévisualisation", "preview": "",
"insert": "Insérer", "insert": "",
"retry": "Recommencer", "retry": "",
"errors": { "errors": {
"promptTooShort": "La requête est trop courte (min {{min}} caractères)", "promptTooShort": "",
"promptTooLong": "La requête est trop longue (max {{max}} caractères)", "promptTooLong": "",
"generationFailed": "Échec de la génération", "generationFailed": "",
"invalidDiagram": "A généré un diagramme non valide :(. Vous pouvez modifier manuellement, réessayer avec la correction automatique, ou essayer une invite différente.", "invalidDiagram": "",
"fixInMermaid": "Modifier Mermaid manuellement →", "fixInMermaid": "",
"aiRepair": "Régénérer (correction automatique) →", "aiRepair": "",
"requestAborted": "Demande abandonnée", "requestAborted": "",
"requestFailed": "La requête a échoué", "requestFailed": "",
"mermaidParseError": "Erreur de syntaxe Mermaid" "mermaidParseError": ""
}, },
"rateLimit": { "rateLimit": {
"messageLimit": "Vous avez atteint votre limite d'IA sur le plan gratuit. Essayez Excalidraw+ pour plus ou revenez demain.", "messageLimit": "",
"generalRateLimit": "Tenez vos chevaux, vous êtes trop rapide pour nous! Veuillez attendre un instant avant de réessayer.", "generalRateLimit": "",
"messageLimitInputPlaceholder": "Vous avez atteint votre limite de messages" "messageLimitInputPlaceholder": ""
}, },
"upsellBtnLabel": "Devenez Premium" "upsellBtnLabel": ""
}, },
"quickSearch": { "quickSearch": {
"placeholder": "Recherche rapide" "placeholder": "Recherche rapide"
+2 -22
View File
@@ -3,10 +3,6 @@
"paste": "Pegar", "paste": "Pegar",
"pasteAsPlaintext": "Pegar coma texto sen formato", "pasteAsPlaintext": "Pegar coma texto sen formato",
"pasteCharts": "Pegar gráficos", "pasteCharts": "Pegar gráficos",
"chartType_bar": "",
"chartType_line": "",
"chartType_radar": "",
"chartType_plaintext": "",
"selectAll": "Seleccionar todo", "selectAll": "Seleccionar todo",
"multiSelect": "Engadir elemento á selección", "multiSelect": "Engadir elemento á selección",
"moveCanvas": "Mover o lenzo", "moveCanvas": "Mover o lenzo",
@@ -53,14 +49,7 @@
"arrowhead_crowfoot_many": "", "arrowhead_crowfoot_many": "",
"arrowhead_crowfoot_one": "", "arrowhead_crowfoot_one": "",
"arrowhead_crowfoot_one_or_many": "", "arrowhead_crowfoot_one_or_many": "",
"arrowhead_cardinality_one": "",
"arrowhead_cardinality_many": "",
"arrowhead_cardinality_one_or_many": "",
"arrowhead_cardinality_exactly_one": "",
"arrowhead_cardinality_zero_or_one": "",
"arrowhead_cardinality_zero_or_many": "",
"more_options": "", "more_options": "",
"cardinality": "",
"arrowtypes": "", "arrowtypes": "",
"arrowtype_sharp": "", "arrowtype_sharp": "",
"arrowtype_round": "", "arrowtype_round": "",
@@ -182,11 +171,7 @@
"linkToElement": "", "linkToElement": "",
"wrapSelectionInFrame": "", "wrapSelectionInFrame": "",
"tab": "", "tab": "",
"shapeSwitch": "", "shapeSwitch": ""
"preferences": "",
"preferences_toolLock": "",
"arrowBinding": "",
"midpointSnapping": ""
}, },
"elementLink": { "elementLink": {
"title": "", "title": "",
@@ -410,10 +395,6 @@
"errorDialog": { "errorDialog": {
"title": "Erro" "title": "Erro"
}, },
"progressDialog": {
"title": "",
"defaultMessage": ""
},
"exportDialog": { "exportDialog": {
"disk_title": "Gardar no disco", "disk_title": "Gardar no disco",
"disk_details": "Exporte os datos da escena a un ficheiro que poderás importar máis tarde.", "disk_details": "Exporte os datos da escena a un ficheiro que poderás importar máis tarde.",
@@ -635,8 +616,7 @@
"syntax": "", "syntax": "",
"preview": "Vista previa", "preview": "Vista previa",
"label": "", "label": "",
"inputPlaceholder": "", "inputPlaceholder": ""
"autoFixAvailable": ""
}, },
"ttd": { "ttd": {
"error": "" "error": ""
+3 -23
View File
@@ -3,10 +3,6 @@
"paste": "הדבקה", "paste": "הדבקה",
"pasteAsPlaintext": "הדבקה ללא עיצוב", "pasteAsPlaintext": "הדבקה ללא עיצוב",
"pasteCharts": "הדבקת תרשימים", "pasteCharts": "הדבקת תרשימים",
"chartType_bar": "",
"chartType_line": "",
"chartType_radar": "",
"chartType_plaintext": "",
"selectAll": "בחירה בהכול", "selectAll": "בחירה בהכול",
"multiSelect": "הוספת רכיב לבחירה", "multiSelect": "הוספת רכיב לבחירה",
"moveCanvas": "הזזת הקנבס", "moveCanvas": "הזזת הקנבס",
@@ -53,14 +49,7 @@
"arrowhead_crowfoot_many": "רגל עורב (הרבה)", "arrowhead_crowfoot_many": "רגל עורב (הרבה)",
"arrowhead_crowfoot_one": "רגל עורב (אחת)", "arrowhead_crowfoot_one": "רגל עורב (אחת)",
"arrowhead_crowfoot_one_or_many": "רגל עורב (אחת או הרבה)", "arrowhead_crowfoot_one_or_many": "רגל עורב (אחת או הרבה)",
"arrowhead_cardinality_one": "",
"arrowhead_cardinality_many": "",
"arrowhead_cardinality_one_or_many": "",
"arrowhead_cardinality_exactly_one": "",
"arrowhead_cardinality_zero_or_one": "",
"arrowhead_cardinality_zero_or_many": "",
"more_options": "אפשרויות נוספות", "more_options": "אפשרויות נוספות",
"cardinality": "",
"arrowtypes": "סוג החץ", "arrowtypes": "סוג החץ",
"arrowtype_sharp": "חץ מחודד", "arrowtype_sharp": "חץ מחודד",
"arrowtype_round": "חץ מעוקל", "arrowtype_round": "חץ מעוקל",
@@ -182,11 +171,7 @@
"linkToElement": "קישור לפריט", "linkToElement": "קישור לפריט",
"wrapSelectionInFrame": "לעטוף את הבחירה במסגרת", "wrapSelectionInFrame": "לעטוף את הבחירה במסגרת",
"tab": "", "tab": "",
"shapeSwitch": "", "shapeSwitch": ""
"preferences": "",
"preferences_toolLock": "",
"arrowBinding": "",
"midpointSnapping": ""
}, },
"elementLink": { "elementLink": {
"title": "קישור לפריט", "title": "קישור לפריט",
@@ -410,10 +395,6 @@
"errorDialog": { "errorDialog": {
"title": "שגיאה" "title": "שגיאה"
}, },
"progressDialog": {
"title": "",
"defaultMessage": ""
},
"exportDialog": { "exportDialog": {
"disk_title": "שמור לכונן", "disk_title": "שמור לכונן",
"disk_details": "ייצא מידע של הקנבאס לקובץ שתוכל לייבא אחר כך.", "disk_details": "ייצא מידע של הקנבאס לקובץ שתוכל לייבא אחר כך.",
@@ -631,12 +612,11 @@
"mermaid": { "mermaid": {
"title": "Mermaid ל־Excalidraw", "title": "Mermaid ל־Excalidraw",
"button": "הוספה", "button": "הוספה",
"description": "", "description": "לעת עתה נתמכים רק <flowchartLink>תרשימי זרימה</flowchartLink>, <sequenceLink>תהליכים</sequenceLink>, <classLink>ודיאגרמת מחלקה</classLink>. שאר הסוגים ייוצרו כתמונות ב-Excalidraw.",
"syntax": "תחביר Mermaid", "syntax": "תחביר Mermaid",
"preview": "תצוגה מקדימה", "preview": "תצוגה מקדימה",
"label": "", "label": "",
"inputPlaceholder": "", "inputPlaceholder": ""
"autoFixAvailable": ""
}, },
"ttd": { "ttd": {
"error": "" "error": ""
+3 -23
View File
@@ -3,10 +3,6 @@
"paste": "पेस्ट", "paste": "पेस्ट",
"pasteAsPlaintext": "सादे पाठ के रूप में चिपकाएं", "pasteAsPlaintext": "सादे पाठ के रूप में चिपकाएं",
"pasteCharts": "चार्ट चिपकाएँ", "pasteCharts": "चार्ट चिपकाएँ",
"chartType_bar": "",
"chartType_line": "",
"chartType_radar": "",
"chartType_plaintext": "",
"selectAll": "सेलेक्ट ऑल", "selectAll": "सेलेक्ट ऑल",
"multiSelect": "अवयव को चयन में सम्मिलित करें", "multiSelect": "अवयव को चयन में सम्मिलित करें",
"moveCanvas": "चित्रपटल को स्थानांतरित करें", "moveCanvas": "चित्रपटल को स्थानांतरित करें",
@@ -53,14 +49,7 @@
"arrowhead_crowfoot_many": "चिड़िया पैर (अनेक)", "arrowhead_crowfoot_many": "चिड़िया पैर (अनेक)",
"arrowhead_crowfoot_one": "चिड़िया पैर (एक)", "arrowhead_crowfoot_one": "चिड़िया पैर (एक)",
"arrowhead_crowfoot_one_or_many": "चिड़िया पैर (एक या अनेक)", "arrowhead_crowfoot_one_or_many": "चिड़िया पैर (एक या अनेक)",
"arrowhead_cardinality_one": "",
"arrowhead_cardinality_many": "",
"arrowhead_cardinality_one_or_many": "",
"arrowhead_cardinality_exactly_one": "",
"arrowhead_cardinality_zero_or_one": "",
"arrowhead_cardinality_zero_or_many": "",
"more_options": "और विकल्प", "more_options": "और विकल्प",
"cardinality": "",
"arrowtypes": "तीर प्रकार", "arrowtypes": "तीर प्रकार",
"arrowtype_sharp": "तीक्ष्ण तीर", "arrowtype_sharp": "तीक्ष्ण तीर",
"arrowtype_round": "गोलाकार तीर", "arrowtype_round": "गोलाकार तीर",
@@ -182,11 +171,7 @@
"linkToElement": "वस्तु की कड़ी", "linkToElement": "वस्तु की कड़ी",
"wrapSelectionInFrame": "चौकट में चुने हुवे को लपेटे", "wrapSelectionInFrame": "चौकट में चुने हुवे को लपेटे",
"tab": "", "tab": "",
"shapeSwitch": "आकार बदलें", "shapeSwitch": "आकार बदलें"
"preferences": "",
"preferences_toolLock": "",
"arrowBinding": "",
"midpointSnapping": ""
}, },
"elementLink": { "elementLink": {
"title": "वस्तु की कड़ी", "title": "वस्तु की कड़ी",
@@ -410,10 +395,6 @@
"errorDialog": { "errorDialog": {
"title": "त्रुटि" "title": "त्रुटि"
}, },
"progressDialog": {
"title": "",
"defaultMessage": ""
},
"exportDialog": { "exportDialog": {
"disk_title": "डिस्क पर सुरक्षित करे", "disk_title": "डिस्क पर सुरक्षित करे",
"disk_details": "दृश्य डेटा एक फ़ाइल में निर्यात करे, जहांसे आप उसे पुनः आयात कर सके", "disk_details": "दृश्य डेटा एक फ़ाइल में निर्यात करे, जहांसे आप उसे पुनः आयात कर सके",
@@ -631,12 +612,11 @@
"mermaid": { "mermaid": {
"title": "मर्मेड से एक्सकाली में", "title": "मर्मेड से एक्सकाली में",
"button": "सन्निवेश करे", "button": "सन्निवेश करे",
"description": "", "description": "वर्तमान में केवल <flowchartLink>बहाव चित्र</flowchartLink>, <sequenceLink> अनुक्रम चित्र </sequenceLink> और <classLink>वर्ग चित्र</classLink> का चित्रिकरण संभव हैं. अन्य चित्र प्रकार एक्सकाली प्रतिमा जैसे चित्रित किए जायेंगे.",
"syntax": "मर्मेड विन्यास", "syntax": "मर्मेड विन्यास",
"preview": "पूर्वावलोकन", "preview": "पूर्वावलोकन",
"label": "", "label": "",
"inputPlaceholder": "", "inputPlaceholder": ""
"autoFixAvailable": ""
}, },
"ttd": { "ttd": {
"error": "" "error": ""
+2 -22
View File
@@ -3,10 +3,6 @@
"paste": "Beillesztés", "paste": "Beillesztés",
"pasteAsPlaintext": "Beillesztés formázatlan szövegként", "pasteAsPlaintext": "Beillesztés formázatlan szövegként",
"pasteCharts": "Grafikon beillesztése", "pasteCharts": "Grafikon beillesztése",
"chartType_bar": "",
"chartType_line": "",
"chartType_radar": "",
"chartType_plaintext": "",
"selectAll": "Összes kijelölése", "selectAll": "Összes kijelölése",
"multiSelect": "Elem hozzáadása a kijelöléshez", "multiSelect": "Elem hozzáadása a kijelöléshez",
"moveCanvas": "Vászon mozgatása", "moveCanvas": "Vászon mozgatása",
@@ -53,14 +49,7 @@
"arrowhead_crowfoot_many": "", "arrowhead_crowfoot_many": "",
"arrowhead_crowfoot_one": "", "arrowhead_crowfoot_one": "",
"arrowhead_crowfoot_one_or_many": "", "arrowhead_crowfoot_one_or_many": "",
"arrowhead_cardinality_one": "",
"arrowhead_cardinality_many": "",
"arrowhead_cardinality_one_or_many": "",
"arrowhead_cardinality_exactly_one": "",
"arrowhead_cardinality_zero_or_one": "",
"arrowhead_cardinality_zero_or_many": "",
"more_options": "", "more_options": "",
"cardinality": "",
"arrowtypes": "Nyíl típus", "arrowtypes": "Nyíl típus",
"arrowtype_sharp": "Hegyes nyíl", "arrowtype_sharp": "Hegyes nyíl",
"arrowtype_round": "Ívelt nyíl", "arrowtype_round": "Ívelt nyíl",
@@ -182,11 +171,7 @@
"linkToElement": "Hivatkozás az objektumhoz", "linkToElement": "Hivatkozás az objektumhoz",
"wrapSelectionInFrame": "", "wrapSelectionInFrame": "",
"tab": "Tab", "tab": "Tab",
"shapeSwitch": "", "shapeSwitch": ""
"preferences": "",
"preferences_toolLock": "",
"arrowBinding": "",
"midpointSnapping": ""
}, },
"elementLink": { "elementLink": {
"title": "Hivatkozás az objektumhoz", "title": "Hivatkozás az objektumhoz",
@@ -410,10 +395,6 @@
"errorDialog": { "errorDialog": {
"title": "Hiba" "title": "Hiba"
}, },
"progressDialog": {
"title": "",
"defaultMessage": ""
},
"exportDialog": { "exportDialog": {
"disk_title": "Mentés lemezre", "disk_title": "Mentés lemezre",
"disk_details": "Exportálja a jelenetadatokat egy fájlba, amelyből később importálhatja.", "disk_details": "Exportálja a jelenetadatokat egy fájlba, amelyből később importálhatja.",
@@ -635,8 +616,7 @@
"syntax": "", "syntax": "",
"preview": "", "preview": "",
"label": "", "label": "",
"inputPlaceholder": "", "inputPlaceholder": ""
"autoFixAvailable": ""
}, },
"ttd": { "ttd": {
"error": "" "error": ""
+3 -23
View File
@@ -3,10 +3,6 @@
"paste": "Tempel", "paste": "Tempel",
"pasteAsPlaintext": "Tempel sebagai teks biasa", "pasteAsPlaintext": "Tempel sebagai teks biasa",
"pasteCharts": "Tempel diagram", "pasteCharts": "Tempel diagram",
"chartType_bar": "",
"chartType_line": "",
"chartType_radar": "",
"chartType_plaintext": "",
"selectAll": "Pilih semua", "selectAll": "Pilih semua",
"multiSelect": "Tambah unsur ke seleksi", "multiSelect": "Tambah unsur ke seleksi",
"moveCanvas": "Pindahkan kanvas", "moveCanvas": "Pindahkan kanvas",
@@ -53,14 +49,7 @@
"arrowhead_crowfoot_many": "", "arrowhead_crowfoot_many": "",
"arrowhead_crowfoot_one": "", "arrowhead_crowfoot_one": "",
"arrowhead_crowfoot_one_or_many": "", "arrowhead_crowfoot_one_or_many": "",
"arrowhead_cardinality_one": "",
"arrowhead_cardinality_many": "",
"arrowhead_cardinality_one_or_many": "",
"arrowhead_cardinality_exactly_one": "",
"arrowhead_cardinality_zero_or_one": "",
"arrowhead_cardinality_zero_or_many": "",
"more_options": "Pilihan lain", "more_options": "Pilihan lain",
"cardinality": "",
"arrowtypes": "Jenis panah", "arrowtypes": "Jenis panah",
"arrowtype_sharp": "Panah runcing", "arrowtype_sharp": "Panah runcing",
"arrowtype_round": "Panah melengkung", "arrowtype_round": "Panah melengkung",
@@ -182,11 +171,7 @@
"linkToElement": "Taut ke objek", "linkToElement": "Taut ke objek",
"wrapSelectionInFrame": "Bungkus pilihan dalam bingkai", "wrapSelectionInFrame": "Bungkus pilihan dalam bingkai",
"tab": "", "tab": "",
"shapeSwitch": "", "shapeSwitch": ""
"preferences": "",
"preferences_toolLock": "",
"arrowBinding": "",
"midpointSnapping": ""
}, },
"elementLink": { "elementLink": {
"title": "Taut ke objek", "title": "Taut ke objek",
@@ -410,10 +395,6 @@
"errorDialog": { "errorDialog": {
"title": "Kesalahan" "title": "Kesalahan"
}, },
"progressDialog": {
"title": "",
"defaultMessage": ""
},
"exportDialog": { "exportDialog": {
"disk_title": "Simpan ke disk", "disk_title": "Simpan ke disk",
"disk_details": "Ekspor data pemandangan ke file yang mana Anda dapat impor nanti.", "disk_details": "Ekspor data pemandangan ke file yang mana Anda dapat impor nanti.",
@@ -631,12 +612,11 @@
"mermaid": { "mermaid": {
"title": "Mermaid menjadi Excalidraw", "title": "Mermaid menjadi Excalidraw",
"button": "Sisipkan", "button": "Sisipkan",
"description": "", "description": "Saat ini hanya <flowchartLink>Flowchart</flowchartLink>, <sequenceLink>Sekuen, </sequenceLink>, dan <classLink>Kelas</classLink>Diagram yang didukung. Jenis lainnya akan dirender sebagai gambar di Excalidraw.",
"syntax": "Syntax Mermaid", "syntax": "Syntax Mermaid",
"preview": "Pratinjau", "preview": "Pratinjau",
"label": "", "label": "",
"inputPlaceholder": "", "inputPlaceholder": ""
"autoFixAvailable": ""
}, },
"ttd": { "ttd": {
"error": "" "error": ""
+7 -27
View File
@@ -3,10 +3,6 @@
"paste": "Incolla", "paste": "Incolla",
"pasteAsPlaintext": "Incolla come testo normale", "pasteAsPlaintext": "Incolla come testo normale",
"pasteCharts": "Incolla grafici", "pasteCharts": "Incolla grafici",
"chartType_bar": "Grafico a barre",
"chartType_line": "Grafico a linee",
"chartType_radar": "Grafico radar",
"chartType_plaintext": "Testo semplice",
"selectAll": "Seleziona tutto", "selectAll": "Seleziona tutto",
"multiSelect": "Aggiungi elemento alla selezione", "multiSelect": "Aggiungi elemento alla selezione",
"moveCanvas": "Sposta tela", "moveCanvas": "Sposta tela",
@@ -53,14 +49,7 @@
"arrowhead_crowfoot_many": "Zampe di gallina (molti)", "arrowhead_crowfoot_many": "Zampe di gallina (molti)",
"arrowhead_crowfoot_one": "Zampa di gallina (una)", "arrowhead_crowfoot_one": "Zampa di gallina (una)",
"arrowhead_crowfoot_one_or_many": "Zampe di gallina (una o molte)", "arrowhead_crowfoot_one_or_many": "Zampe di gallina (una o molte)",
"arrowhead_cardinality_one": "",
"arrowhead_cardinality_many": "",
"arrowhead_cardinality_one_or_many": "",
"arrowhead_cardinality_exactly_one": "",
"arrowhead_cardinality_zero_or_one": "",
"arrowhead_cardinality_zero_or_many": "",
"more_options": "Altre opzioni", "more_options": "Altre opzioni",
"cardinality": "",
"arrowtypes": "Tipo di freccia", "arrowtypes": "Tipo di freccia",
"arrowtype_sharp": "Freccia affilata", "arrowtype_sharp": "Freccia affilata",
"arrowtype_round": "Freccia curva", "arrowtype_round": "Freccia curva",
@@ -182,11 +171,7 @@
"linkToElement": "Link all'oggetto", "linkToElement": "Link all'oggetto",
"wrapSelectionInFrame": "Avvolgi la selezione nella cornice", "wrapSelectionInFrame": "Avvolgi la selezione nella cornice",
"tab": "Scheda", "tab": "Scheda",
"shapeSwitch": "Cambia forma", "shapeSwitch": "Cambia forma"
"preferences": "Preferenze",
"preferences_toolLock": "Blocco strumento",
"arrowBinding": "Legatura a freccia",
"midpointSnapping": "Aggancia ai punti medi"
}, },
"elementLink": { "elementLink": {
"title": "Link all'oggetto", "title": "Link all'oggetto",
@@ -410,10 +395,6 @@
"errorDialog": { "errorDialog": {
"title": "Errore" "title": "Errore"
}, },
"progressDialog": {
"title": "",
"defaultMessage": ""
},
"exportDialog": { "exportDialog": {
"disk_title": "Salva su disco", "disk_title": "Salva su disco",
"disk_details": "Esporta i dati della scena su file, dal quale potrai importare in seguito.", "disk_details": "Esporta i dati della scena su file, dal quale potrai importare in seguito.",
@@ -576,9 +557,9 @@
}, },
"welcomeScreen": { "welcomeScreen": {
"app": { "app": {
"center_heading": "I tuoi disegni vengono salvati nella memoria del tuo browser.", "center_heading": "",
"center_heading_line2": "La memoria del browser potrebbe essere cancellata inaspettatamente.", "center_heading_line2": "",
"center_heading_line3": "Salva regolarmente il tuo lavoro in un file per evitare di perderlo.", "center_heading_line3": "",
"center_heading_plus": "Volevi invece andare su Excalidraw+?", "center_heading_plus": "Volevi invece andare su Excalidraw+?",
"menuHint": "Esporta, preferenze, lingue, ..." "menuHint": "Esporta, preferenze, lingue, ..."
}, },
@@ -631,12 +612,11 @@
"mermaid": { "mermaid": {
"title": "Da Mermaid a Excalidraw", "title": "Da Mermaid a Excalidraw",
"button": "Inserisci", "button": "Inserisci",
"description": "", "description": "Attualmente sono supportati solo diagrammi di <flowchartLink>flusso</flowchartLink>,<sequenceLink> sequenza, </sequenceLink> e <classLink>classe </classLink>. Gli altri tipi saranno rappresentati come immagini in Excalidraw.",
"syntax": "Sintassi Mermaid", "syntax": "Sintassi Mermaid",
"preview": "Anteprima", "preview": "Anteprima",
"label": "Mermaid", "label": "Mermaid",
"inputPlaceholder": "Scrivi qui la definizione del diagramma Mermaid...", "inputPlaceholder": "Scrivi qui la definizione del diagramma Mermaid..."
"autoFixAvailable": "Correzione automatica disponibile"
}, },
"ttd": { "ttd": {
"error": "Errore!" "error": "Errore!"
@@ -661,7 +641,7 @@
"placeholder": { "placeholder": {
"title": "Progettiamo il tuo diagramma", "title": "Progettiamo il tuo diagramma",
"description": "Descrivi il diagramma che vuoi creare e noi lo genereremo per te.", "description": "Descrivi il diagramma che vuoi creare e noi lo genereremo per te.",
"hint": "" "hint": "Al momento conosciamo i diagrammi di flusso, di sequenza e di classe."
}, },
"preview": "Anteprima", "preview": "Anteprima",
"insert": "Inserisci", "insert": "Inserisci",
+142 -162
View File
@@ -3,10 +3,6 @@
"paste": "貼り付け", "paste": "貼り付け",
"pasteAsPlaintext": "書式なしテキストとして貼り付け", "pasteAsPlaintext": "書式なしテキストとして貼り付け",
"pasteCharts": "チャートの貼り付け", "pasteCharts": "チャートの貼り付け",
"chartType_bar": "",
"chartType_line": "",
"chartType_radar": "",
"chartType_plaintext": "",
"selectAll": "すべて選択", "selectAll": "すべて選択",
"multiSelect": "複数選択", "multiSelect": "複数選択",
"moveCanvas": "キャンバスを移動", "moveCanvas": "キャンバスを移動",
@@ -38,7 +34,7 @@
"opacity": "透明度", "opacity": "透明度",
"textAlign": "文字の配置", "textAlign": "文字の配置",
"edges": "角", "edges": "角",
"sharp": "シャープ", "sharp": "四角",
"round": "丸", "round": "丸",
"arrowheads": "線の終点", "arrowheads": "線の終点",
"arrowhead_none": "なし", "arrowhead_none": "なし",
@@ -50,21 +46,14 @@
"arrowhead_triangle_outline": "三角 (中抜き)", "arrowhead_triangle_outline": "三角 (中抜き)",
"arrowhead_diamond": "ひし形", "arrowhead_diamond": "ひし形",
"arrowhead_diamond_outline": "ひし形 (中抜き)", "arrowhead_diamond_outline": "ひし形 (中抜き)",
"arrowhead_crowfoot_many": "カラスの足 (*)", "arrowhead_crowfoot_many": "鳥の足記法(多対多)",
"arrowhead_crowfoot_one": "カラスの足 (1)", "arrowhead_crowfoot_one": "鳥の足記法(一対一)",
"arrowhead_crowfoot_one_or_many": "カラスの足 (1..*)", "arrowhead_crowfoot_one_or_many": "鳥の足記法(一対多)",
"arrowhead_cardinality_one": "", "more_options": "詳細設定",
"arrowhead_cardinality_many": "", "arrowtypes": "矢印の種類",
"arrowhead_cardinality_one_or_many": "",
"arrowhead_cardinality_exactly_one": "",
"arrowhead_cardinality_zero_or_one": "",
"arrowhead_cardinality_zero_or_many": "",
"more_options": "その他のオプション",
"cardinality": "",
"arrowtypes": "矢印タイプ",
"arrowtype_sharp": "鋭い矢印", "arrowtype_sharp": "鋭い矢印",
"arrowtype_round": "曲線矢印", "arrowtype_round": "曲線矢印",
"arrowtype_elbowed": "折れ線矢印", "arrowtype_elbowed": "ひじ矢印",
"fontSize": "フォントの大きさ", "fontSize": "フォントの大きさ",
"fontFamily": "フォントの種類", "fontFamily": "フォントの種類",
"addWatermark": "\"Made with Excalidraw\"と表示", "addWatermark": "\"Made with Excalidraw\"と表示",
@@ -86,14 +75,14 @@
"right": "右寄せ", "right": "右寄せ",
"extraBold": "極太", "extraBold": "極太",
"architect": "建築家", "architect": "建築家",
"artist": "画家", "artist": "アーティスト",
"cartoonist": "漫画家", "cartoonist": "漫画家",
"fileTitle": "ファイル名", "fileTitle": "ファイル名",
"colorPicker": "カラーピッカー", "colorPicker": "カラーピッカー",
"canvasColors": "キャンバス上で使用", "canvasColors": "キャンバス上で使用",
"canvasBackground": "キャンバスの背景", "canvasBackground": "キャンバスの背景",
"drawingCanvas": "キャンバスの描画", "drawingCanvas": "キャンバスの描画",
"clearCanvas": "キャンバスを消去", "clearCanvas": "キャンバスを片付ける",
"layers": "レイヤー", "layers": "レイヤー",
"actions": "操作", "actions": "操作",
"language": "言語", "language": "言語",
@@ -112,7 +101,7 @@
"libraryLoadingMessage": "ライブラリを読み込み中…", "libraryLoadingMessage": "ライブラリを読み込み中…",
"libraries": "ライブラリを参照する", "libraries": "ライブラリを参照する",
"loadingScene": "シーンを読み込み中…", "loadingScene": "シーンを読み込み中…",
"loadScene": "ファイルからシーンを開く", "loadScene": "ファイルからシーン",
"align": "配置", "align": "配置",
"alignTop": "上揃え", "alignTop": "上揃え",
"alignBottom": "下揃え", "alignBottom": "下揃え",
@@ -171,22 +160,18 @@
"prompt": "プロンプト", "prompt": "プロンプト",
"followUs": "フォローする", "followUs": "フォローする",
"discordChat": "Discord チャット", "discordChat": "Discord チャット",
"zoomToFitViewport": "表範囲に合わせてズーム", "zoomToFitViewport": "表寿範囲に合わせてズーム",
"zoomToFitSelection": "選択範囲に合わせてズーム", "zoomToFitSelection": "選択範囲に合わせてズーム",
"zoomToFit": "すべての要素が収まるようにズーム", "zoomToFit": "すべての要素が収まるようにズーム",
"installPWA": "Excalidrawをローカルにインストール(PWA)", "installPWA": "Excalidrawをローカルにインストール(PWA)",
"autoResize": "テキストの自動サイズ変更を有効化", "autoResize": "テキストの自動サイズ変更を有効化",
"imageCropping": "画像の切り抜き", "imageCropping": "画像のトリミング",
"unCroppedDimension": "元のサイズ", "unCroppedDimension": "",
"copyElementLink": "オブジェクトへのリンクをコピー", "copyElementLink": "",
"linkToElement": "オブジェクトにリンク", "linkToElement": "オブジェクトにリンク",
"wrapSelectionInFrame": "選択範囲をフレームで囲む", "wrapSelectionInFrame": "選択範囲を枠で折り返す",
"tab": "Tab", "tab": "Tab",
"shapeSwitch": "図形形状を変更", "shapeSwitch": "図形形状を変更"
"preferences": "",
"preferences_toolLock": "",
"arrowBinding": "",
"midpointSnapping": ""
}, },
"elementLink": { "elementLink": {
"title": "オブジェクトにリンク", "title": "オブジェクトにリンク",
@@ -200,15 +185,15 @@
"search": { "search": {
"inputPlaceholder": "ライブラリを検索", "inputPlaceholder": "ライブラリを検索",
"heading": "ライブラリと一致", "heading": "ライブラリと一致",
"noResults": "一致するアイテムはありません…", "noResults": "一致するアイテムが見つかりませんでした…",
"clearSearch": "検索のクリア" "clearSearch": "検索のクリア"
} }
}, },
"search": { "search": {
"title": "キャンバスで検索", "title": "キャンバスで検索",
"noMatch": "一致する結果はありません…", "noMatch": "一致なし…",
"singleResult": "", "singleResult": "結果",
"multipleResults": "", "multipleResults": "結果数",
"placeholder": "キャンバス内のテキストを検索…", "placeholder": "キャンバス内のテキストを検索…",
"frames": "フレーム", "frames": "フレーム",
"texts": "テキスト" "texts": "テキスト"
@@ -255,7 +240,7 @@
"embeddableInteractionButton": "クリックして操作" "embeddableInteractionButton": "クリックして操作"
}, },
"alerts": { "alerts": {
"clearReset": "キャンバス全体を消去します。本当によろしいですか?", "clearReset": "この操作によってキャンバス全体が消えます。よろしいですか?",
"couldNotCreateShareableLink": "共有URLを作成できませんでした。", "couldNotCreateShareableLink": "共有URLを作成できませんでした。",
"couldNotCreateShareableLinkTooBig": "共有可能なリンクを作成できませんでした: シーンが大きすぎます", "couldNotCreateShareableLinkTooBig": "共有可能なリンクを作成できませんでした: シーンが大きすぎます",
"couldNotLoadInvalidFile": "無効なファイルを読み込めませんでした。", "couldNotLoadInvalidFile": "無効なファイルを読み込めませんでした。",
@@ -264,8 +249,8 @@
"couldNotCopyToClipboard": "クリップボードにコピーできませんでした。", "couldNotCopyToClipboard": "クリップボードにコピーできませんでした。",
"decryptFailed": "データを復号できませんでした。", "decryptFailed": "データを復号できませんでした。",
"uploadedSecurly": "データのアップロードはエンドツーエンド暗号化によって保護されています。Excalidrawサーバーと第三者はデータの内容を見ることができません。", "uploadedSecurly": "データのアップロードはエンドツーエンド暗号化によって保護されています。Excalidrawサーバーと第三者はデータの内容を見ることができません。",
"loadSceneOverridePrompt": "外部の描画データを読み込むと、既存のコンテンツが置き換わります。続行しますか?", "loadSceneOverridePrompt": "外部図面を読み込むと、既存のコンテンツが置き換わります。続行しますか?",
"collabStopOverridePrompt": "セッションを停止すると、ローカルに保存されている図が上書きされます。 本当によろしいですか?\n\n(ローカルの図を保持したい場合は、セッションを停止せずにブラウザーのタブを閉じてください。)", "collabStopOverridePrompt": "セッションを停止すると、ローカルに保存されている図が上書きされます。 本当によろしいですか?\n\n(ローカルの図を保持したい場合は、セッションを停止せずにブラウザタブを閉じてください。)",
"errorAddingToLibrary": "アイテムをライブラリに追加できませんでした", "errorAddingToLibrary": "アイテムをライブラリに追加できませんでした",
"errorRemovingFromLibrary": "ライブラリからアイテムを削除できませんでした", "errorRemovingFromLibrary": "ライブラリからアイテムを削除できませんでした",
"confirmAddLibrary": "{{numShapes}} 個の図形をライブラリに追加します。よろしいですか?", "confirmAddLibrary": "{{numShapes}} 個の図形をライブラリに追加します。よろしいですか?",
@@ -276,7 +261,7 @@
"removeItemsFromsLibrary": "{{count}} 個のアイテムをライブラリから削除しますか?", "removeItemsFromsLibrary": "{{count}} 個のアイテムをライブラリから削除しますか?",
"invalidEncryptionKey": "暗号化キーは22文字でなければなりません。共同編集は無効化されています。", "invalidEncryptionKey": "暗号化キーは22文字でなければなりません。共同編集は無効化されています。",
"collabOfflineWarning": "インターネットに接続されていません。\n変更は保存されません!", "collabOfflineWarning": "インターネットに接続されていません。\n変更は保存されません!",
"localStorageQuotaExceeded": "ブラウザーのストレージ容量を超えました。変更は保存されません。" "localStorageQuotaExceeded": ""
}, },
"errors": { "errors": {
"unsupportedFileType": "サポートされていないファイル形式です。", "unsupportedFileType": "サポートされていないファイル形式です。",
@@ -286,13 +271,13 @@
"failedToFetchImage": "画像の読み込みに失敗しました。", "failedToFetchImage": "画像の読み込みに失敗しました。",
"cannotResolveCollabServer": "コラボレーションサーバに接続できませんでした。ページを再読み込みして、もう一度お試しください。", "cannotResolveCollabServer": "コラボレーションサーバに接続できませんでした。ページを再読み込みして、もう一度お試しください。",
"importLibraryError": "ライブラリを読み込めませんでした。", "importLibraryError": "ライブラリを読み込めませんでした。",
"saveLibraryError": "ライブラリをストレージに保存できませんでした。変更を失わないように、ローカルにファイルとして保存してください。", "saveLibraryError": "",
"collabSaveFailed": "バックエンドデータベースに保存できませんでした。問題が解決しない場合は、作業を失わないようにローカルにファイルを保存してください。", "collabSaveFailed": "バックエンドデータベースに保存できませんでした。問題が解決しない場合は、作業を失わないようにローカルにファイルを保存してください。",
"collabSaveFailed_sizeExceeded": "キャンバスが大きすぎるため、バックエンドデータベースに保存できませんでした。問題が解決しない場合は、作業を失わないようにローカルにファイルを保存してください。", "collabSaveFailed_sizeExceeded": "キャンバスが大きすぎるため、バックエンドデータベースに保存できませんでした。問題が解決しない場合は、作業を失わないようにローカルにファイルを保存してください。",
"imageToolNotSupported": "画像ツールは使用不可です。", "imageToolNotSupported": "画像ツールは使用不可です。",
"brave_measure_text_error": { "brave_measure_text_error": {
"line1": "<bold>Aggressly Block Fingerprinting</bold> 設定が有効なBraveブラウザを使用しているようです。", "line1": "<bold>Aggressly Block Fingerprinting</bold> 設定が有効なBraveブラウザを使用しているようです。",
"line2": "これにより、描画内の<bold>テキスト要素</bold>が壊れる可能性があります。", "line2": "これにより、図面の <bold>テキスト要素</bold> が壊れる可能性があります。",
"line3": "この設定を無効にすることを強く推奨します。 <link>設定手順</link> をこちらから確認できます。", "line3": "この設定を無効にすることを強く推奨します。 <link>設定手順</link> をこちらから確認できます。",
"line4": "この設定を無効にすると、テキスト要素の表示が修正されません。 GitHub で <issueLink>Issue</issueLink> を開くか、 <discordLink>Discord</discordLink> にご記入ください" "line4": "この設定を無効にすると、テキスト要素の表示が修正されません。 GitHub で <issueLink>Issue</issueLink> を開くか、 <discordLink>Discord</discordLink> にご記入ください"
}, },
@@ -307,9 +292,9 @@
}, },
"toolBar": { "toolBar": {
"selection": "選択", "selection": "選択",
"lasso": "なげなわ選択", "lasso": "",
"image": "画像を挿入", "image": "画像を挿入",
"rectangle": "長方形", "rectangle": "形",
"diamond": "ひし形", "diamond": "ひし形",
"ellipse": "楕円", "ellipse": "楕円",
"arrow": "矢印", "arrow": "矢印",
@@ -319,31 +304,31 @@
"library": "ライブラリ", "library": "ライブラリ",
"lock": "描画後も使用中のツールを選択したままにする", "lock": "描画後も使用中のツールを選択したままにする",
"penMode": "ペンモード - タッチ防止", "penMode": "ペンモード - タッチ防止",
"link": "選択した図形にリンクを追加・更新", "link": "",
"eraser": "消しゴム", "eraser": "消しゴム",
"frame": "フレーム", "frame": "フレームツール",
"magicframe": "ワイヤーフレームからコードを生成", "magicframe": "ワイヤーフレームからコードを生成",
"embeddable": "Web埋め込み", "embeddable": "Web埋め込み",
"laser": "レーザーポインター", "laser": "レーザーポインター",
"hand": "手 (パンニングツール)", "hand": "手 (パンニングツール)",
"extraTools": "その他のツール", "extraTools": "その他のツール",
"mermaidToExcalidraw": "Mermaid を Excalidraw に変換", "mermaidToExcalidraw": "Mermaid を Excalidraw に変換",
"convertElementType": "図形タイプを切り替え" "convertElementType": ""
}, },
"element": { "element": {
"rectangle": "長方形", "rectangle": "",
"diamond": "ひし形", "diamond": "",
"ellipse": "楕円", "ellipse": "楕円",
"arrow": "矢印", "arrow": "",
"line": "", "line": "",
"freedraw": "フリーハンド", "freedraw": "",
"text": "文字", "text": "文字",
"image": "画像", "image": "画像",
"group": "グループ", "group": "グループ",
"frame": "フレーム", "frame": "フレーム",
"magicframe": "ワイヤーフレームからコードを生成", "magicframe": "ワイヤーフレームからコードを生成",
"embeddable": "Web埋め込み", "embeddable": "",
"selection": "選択", "selection": "",
"iframe": "IFrame" "iframe": "IFrame"
}, },
"headings": { "headings": {
@@ -352,34 +337,34 @@
"shapes": "図形" "shapes": "図形"
}, },
"hints": { "hints": {
"dismissSearch": "{{shortcut}} で検索を閉じる", "dismissSearch": "",
"canvasPanning": "キャンバスを移動するには、{{shortcut_1}} か {{shortcut_2}} を押しながらドラッグ、または手のひらツールを使用", "canvasPanning": "",
"linearElement": "クリックすると複数の頂点からなる曲線を開始、ドラッグすると直線", "linearElement": "クリックすると複数の頂点からなる曲線を開始、ドラッグすると直線",
"arrowTool": "クリックで複数の点を追加、ドラッグで直線。{{shortcut}} を再度押すと矢印タイプが変更されます。", "arrowTool": "",
"arrowBindModifiers": "{{shortcut_1}} を押し続けるとバインドを無効化、{{shortcut_2}} を押し続けると固定点にバインド", "arrowBindModifiers": "",
"freeDraw": "クリックしてドラッグします。離すと終了します", "freeDraw": "クリックしてドラッグします。離すと終了します",
"text": "ヒント: 選択ツールを使用して任意の場所をダブルクリックしてテキストを追加することもできます", "text": "ヒント: 選択ツールを使用して任意の場所をダブルクリックしてテキストを追加することもできます",
"embeddable": "クリックしてドラッグし、ウェブサイトを埋め込む", "embeddable": "クリックしてドラッグし、ウェブサイトを埋め込む",
"text_selected": "ダブルクリック、または {{shortcut}} を押してテキストを編集", "text_selected": "",
"text_editing": "{{shortcut_1}} または {{shortcut_2}} を押して編集を終了", "text_editing": "",
"linearElementMulti": "最後の点をクリック、または {{shortcut_1}} か {{shortcut_2}} を押して完了", "linearElementMulti": "",
"lockAngle": "{{shortcut}} を押し続けて角度を固定", "lockAngle": "",
"resize": "{{shortcut_1}} を押し続けて縦横比を維持、\n{{shortcut_2}} を押し続けて中心からリサイズ", "resize": "",
"resizeImage": "{{shortcut_1}} を押し続けて自由にリサイズ、\n{{shortcut_2}} を押し続けて中心からリサイズ", "resizeImage": "",
"rotate": "{{shortcut}} を押し続けて角度を固定して回転", "rotate": "",
"lineEditor_info": "{{shortcut_1}} を押しながらダブルクリック、または {{shortcut_2}} を押して点を編集", "lineEditor_info": "",
"lineEditor_line_info": "ダブルクリック、または {{shortcut}} を押して点を編集", "lineEditor_line_info": "",
"lineEditor_pointSelected": "{{shortcut_1}} で点を削除、\n{{shortcut_2}} で複製、またはドラッグで移動", "lineEditor_pointSelected": "",
"lineEditor_nothingSelected": "点を選択して編集 ({{shortcut_1}} を押し続けて複数選択)、\nまたは {{shortcut_2}} を押しながらクリックで新しい点を追加", "lineEditor_nothingSelected": "",
"publishLibrary": "自分のライブラリを公開", "publishLibrary": "自分のライブラリを公開",
"bindTextToElement": "{{shortcut}} でテキストを追加", "bindTextToElement": "",
"createFlowchart": "{{shortcut}} でフローチャートを作成", "createFlowchart": "",
"deepBoxSelect": "{{shortcut}} を押し続けて詳細選択・ドラッグ防止", "deepBoxSelect": "",
"eraserRevert": "{{shortcut}} を押し続けて削除マークを取り消し", "eraserRevert": "",
"firefox_clipboard_write": "この機能は、\"dom.events.asyncClipboard.clipboardItem\" フラグを \"true\" に設定することで有効になる可能性があります。Firefox でブラウザーの設定を変更するには、\"about:config\" ページを参照してください。", "firefox_clipboard_write": "この機能は、\"dom.events.asyncClipboard.clipboardItem\" フラグを \"true\" に設定することで有効になる可能性があります。Firefox でブラウザーの設定を変更するには、\"about:config\" ページを参照してください。",
"disableSnapping": "{{shortcut}} を押し続けてスナップを無効化", "disableSnapping": "",
"enterCropEditor": "画像をダブルクリック、または {{shortcut}} を押して切り抜き", "enterCropEditor": "",
"leaveCropEditor": "画像の外をクリック、または {{shortcut_1}} か {{shortcut_2}} を押して切り抜きを終了" "leaveCropEditor": ""
}, },
"canvasError": { "canvasError": {
"cannotShowPreview": "プレビューを表示できません", "cannotShowPreview": "プレビューを表示できません",
@@ -388,17 +373,17 @@
}, },
"errorSplash": { "errorSplash": {
"headingMain": "エラーが発生しました。もう一度やり直してください。 <button>ページを再読み込みする。</button>", "headingMain": "エラーが発生しました。もう一度やり直してください。 <button>ページを再読み込みする。</button>",
"clearCanvasMessage": "再読み込みがうまくいかない場合は、<button>キャンバスを消去</button>してみてください。", "clearCanvasMessage": "再読み込みがうまくいかない場合は、 <button>キャンバスを消去しています</button>",
"clearCanvasCaveat": " これにより作業が失われます ", "clearCanvasCaveat": " これにより作業が失われます ",
"trackedToSentry": "エラー (識別子: {{eventId}}) はシステムに記録されました。", "trackedToSentry": "識別子のエラー {{eventId}} が我々のシステムで追跡されました。",
"openIssueMessage": "エラーにシーン情報が含まれないよう配慮しています。シーンが非公開でなければ、<button>バグ報告</button>へのご協力をお願いします。以下の情報をコピーしてGitHub Issueに貼り付けてください。", "openIssueMessage": "エラーに関するシーン情報を含めないように非常に慎重に設定しました。もしあなたのシーンがプライベートでない場合は、私たちのフォローアップを検討してください。 <button>バグ報告</button> GitHub Issueに以下の情報をコピーして貼り付けてください。",
"sceneContent": "シーンの内容:" "sceneContent": "シーンの内容:"
}, },
"shareDialog": { "shareDialog": {
"or": "または" "or": "または"
}, },
"roomDialog": { "roomDialog": {
"desc_intro": "他の人を描画の共同編集に招待しましょう。", "desc_intro": "図面にコラボレーションするよう人々を招待しま。",
"desc_privacy": "心配しないでください、セッションはエンドツーエンドで暗号化されており、完全にプライベートです。私たちのサーバーでさえも、あなたが描いたものを見ることができません。", "desc_privacy": "心配しないでください、セッションはエンドツーエンドで暗号化されており、完全にプライベートです。私たちのサーバーでさえも、あなたが描いたものを見ることができません。",
"button_startSession": "セッションを開始する", "button_startSession": "セッションを開始する",
"button_stopSession": "セッションを終了する", "button_stopSession": "セッションを終了する",
@@ -410,10 +395,6 @@
"errorDialog": { "errorDialog": {
"title": "エラー" "title": "エラー"
}, },
"progressDialog": {
"title": "",
"defaultMessage": ""
},
"exportDialog": { "exportDialog": {
"disk_title": "ディスクに保存", "disk_title": "ディスクに保存",
"disk_details": "シーンデータを後からインポートできるファイルにエクスポートします。", "disk_details": "シーンデータを後からインポートできるファイルにエクスポートします。",
@@ -430,8 +411,8 @@
"click": "クリック", "click": "クリック",
"deepSelect": "深い選択", "deepSelect": "深い選択",
"deepBoxSelect": "ボックス内の深い選択、およびドラッグの抑止", "deepBoxSelect": "ボックス内の深い選択、およびドラッグの抑止",
"createFlowchart": "汎用要素からフローチャートを作成", "createFlowchart": "",
"navigateFlowchart": "フローチャート内を移動", "navigateFlowchart": "",
"curvedArrow": "カーブした矢印", "curvedArrow": "カーブした矢印",
"curvedLine": "曲線", "curvedLine": "曲線",
"documentation": "ドキュメント", "documentation": "ドキュメント",
@@ -455,8 +436,8 @@
"toggleElementLock": "選択したアイテムをロック/ロック解除", "toggleElementLock": "選択したアイテムをロック/ロック解除",
"movePageUpDown": "ページを上下に移動", "movePageUpDown": "ページを上下に移動",
"movePageLeftRight": "ページを左右に移動", "movePageLeftRight": "ページを左右に移動",
"cropStart": "画像を切り抜き", "cropStart": "",
"cropFinish": "画像の切り抜きを終了" "cropFinish": ""
}, },
"clearCanvasDialog": { "clearCanvasDialog": {
"title": "キャンバスを消去" "title": "キャンバスを消去"
@@ -482,10 +463,10 @@
"required": "必須項目", "required": "必須項目",
"website": "有効な URL を入力してください" "website": "有効な URL を入力してください"
}, },
"noteDescription": "あなたのライブラリを<link>公開ライブラリリポジトリ</link>に投稿して、他の人が作図に使えるようにしましょう。", "noteDescription": "以下に含めるライブラリを提出してください <link>公開ライブラリリポジトリ</link>他の人が作図に使えるようにするためです",
"noteGuidelines": "投稿されたライブラリは担当者が審査します。投稿前に<link>ガイドライン</link>をお読みください。修正をお願いすることがあるため、GitHubアカウントがあると便利ですが、必須ではありません。", "noteGuidelines": "最初にライブラリを手動で承認する必要があります。次をお読みください <link>ガイドライン</link> 送信する前に、GitHubアカウントが必要になりますが、必須ではありません。",
"noteLicense": "投稿すること、ライブラリが<link>MITライセンス</link>で公開されることに同意したものとみなします。これは誰でも自由に利用できることを意味します。", "noteLicense": "提出することにより、ライブラリが次の下で公開されることに同意します: <link>MIT ライセンス </link>つまり誰でも制限なく使えるということです",
"noteItems": "各アイテムにはフィルタリング用に固有の名前が必要です。以下のアイテムが含まれます:", "noteItems": "各ライブラリ項目は、フィルタリングのために独自の名前を持つ必要があります。以下のライブラリアイテムが含まれます:",
"atleastOneLibItem": "開始するには少なくとも1つのライブラリ項目を選択してください", "atleastOneLibItem": "開始するには少なくとも1つのライブラリ項目を選択してください",
"republishWarning": "注意: 選択された項目の中には、すでに公開/投稿済みと表示されているものがあります。既存のライブラリや投稿を更新する場合のみ、アイテムを再投稿してください。" "republishWarning": "注意: 選択された項目の中には、すでに公開/投稿済みと表示されているものがあります。既存のライブラリや投稿を更新する場合のみ、アイテムを再投稿してください。"
}, },
@@ -527,15 +508,15 @@
}, },
"stats": { "stats": {
"angle": "角度", "angle": "角度",
"shapes": "図形", "shapes": "",
"height": "高さ", "height": "高さ",
"scene": "シーン", "scene": "シーン",
"selected": "選択済み", "selected": "選択済み",
"storage": "ストレージ", "storage": "ストレージ",
"fullTitle": "キャンバス・図形のプロパティ", "fullTitle": "",
"title": "プロパティ", "title": "プロパティ",
"generalStats": "全般", "generalStats": "",
"elementProperties": "図形のプロパティ", "elementProperties": "",
"total": "合計", "total": "合計",
"version": "バージョン", "version": "バージョン",
"versionCopy": "クリックしてコピー", "versionCopy": "クリックしてコピー",
@@ -547,7 +528,7 @@
"copyStyles": "スタイルをコピーしました。", "copyStyles": "スタイルをコピーしました。",
"copyToClipboard": "クリップボードにコピー", "copyToClipboard": "クリップボードにコピー",
"copyToClipboardAsPng": "{{exportSelection}} を PNG 形式でクリップボードにコピーしました\n({{exportColorScheme}})", "copyToClipboardAsPng": "{{exportSelection}} を PNG 形式でクリップボードにコピーしました\n({{exportColorScheme}})",
"copyToClipboardAsSvg": "{{exportSelection}} を SVG 形式でクリップボードにコピーしました\n({{exportColorScheme}})", "copyToClipboardAsSvg": "",
"fileSaved": "ファイルを保存しました", "fileSaved": "ファイルを保存しました",
"fileSavedToFilename": "{filename} に保存しました", "fileSavedToFilename": "{filename} に保存しました",
"canvas": "キャンバス", "canvas": "キャンバス",
@@ -555,7 +536,7 @@
"pasteAsSingleElement": "{{shortcut}} を使用して単一の要素として貼り付けるか、\n既存のテキストエディタに貼り付け", "pasteAsSingleElement": "{{shortcut}} を使用して単一の要素として貼り付けるか、\n既存のテキストエディタに貼り付け",
"unableToEmbed": "この URL の埋め込みは現在許可されていません。URL のホワイトリストへの追加をリクエストするには、GitHub で Issue を上げてください。", "unableToEmbed": "この URL の埋め込みは現在許可されていません。URL のホワイトリストへの追加をリクエストするには、GitHub で Issue を上げてください。",
"unrecognizedLinkFormat": "埋め込もうとしたリンクは期待するフォーマットと一致しません。埋め込み元のサイトで提供される「embed」の文字列を貼り付けてください。", "unrecognizedLinkFormat": "埋め込もうとしたリンクは期待するフォーマットと一致しません。埋め込み元のサイトで提供される「embed」の文字列を貼り付けてください。",
"elementLinkCopied": "リンクをクリップボードにコピーしました" "elementLinkCopied": ""
}, },
"colors": { "colors": {
"transparent": "透明", "transparent": "透明",
@@ -576,9 +557,9 @@
}, },
"welcomeScreen": { "welcomeScreen": {
"app": { "app": {
"center_heading": "描画データはブラウザーのストレージに保存されます。", "center_heading": "",
"center_heading_line2": "ブラウザーのストレージは予期せず消去されることがあります。", "center_heading_line2": "",
"center_heading_line3": "作業を失わないよう、定期的にファイルへ保存してください。", "center_heading_line3": "",
"center_heading_plus": "代わりにExcalidraw+を開きますか?", "center_heading_plus": "代わりにExcalidraw+を開きますか?",
"menuHint": "エクスポート、設定、言語..." "menuHint": "エクスポート、設定、言語..."
}, },
@@ -590,7 +571,7 @@
} }
}, },
"colorPicker": { "colorPicker": {
"color": "", "color": "",
"mostUsedCustomColors": "最も使用されているカスタム色", "mostUsedCustomColors": "最も使用されているカスタム色",
"colors": "色", "colors": "色",
"shades": "影", "shades": "影",
@@ -619,77 +600,76 @@
"loadFromFile": { "loadFromFile": {
"title": "ファイルからロード", "title": "ファイルからロード",
"button": "ファイルからロード", "button": "ファイルからロード",
"description": "ファイルからの読み込みは、<bold>現在の描画内容を置き換えます</bold>。<br></br>その前に、以下の選択肢のいずれかにより描画内容を保存できます。" "description": "ファイルからのロードは、<bold>現在の描画内容を置き換えます</bold>。<br></br>その前に、以下の選択肢のいずれかにより描画内容を保存できます。"
}, },
"shareableLink": { "shareableLink": {
"title": "リンクから読み込み", "title": "リンクからロード",
"button": "描画内容を置き換える", "button": "描画内容を置き換える",
"description": "外部の描画データの読み込みは、<bold>現在の描画内容を置き換えます</bold>。<br></br>その前に、以下の選択肢のいずれかにより描画内容を保存できます。" "description": "外部図面のロードは、<bold>現在の描画内容を置き換えます</bold>。<br></br>その前に、以下の選択肢のいずれかにより描画内容を保存できます。"
} }
} }
}, },
"mermaid": { "mermaid": {
"title": "Mermaid を Excalidraw に変換", "title": "Mermaid を Excalidraw に変換",
"button": "挿入", "button": "挿入",
"description": "", "description": "現在、<flowchartLink>Flowchart</flowchartLink>、<sequenceLink>Sequence</sequenceLink>、<classLink>Class</classLink> のダイアグラムのみに対応しています。その他の種類は、Excalidraw では画像として描画されます。",
"syntax": "Mermaid 構文", "syntax": "Mermaid 構文",
"preview": "プレビュー", "preview": "プレビュー",
"label": "Mermaid", "label": "",
"inputPlaceholder": "Mermaid のダイアグラム定義をここに入力...", "inputPlaceholder": ""
"autoFixAvailable": ""
}, },
"ttd": { "ttd": {
"error": "エラー!" "error": ""
}, },
"chat": { "chat": {
"inputPlaceholder": "ダイアグラムのアイデアを入力... ({{shortcut}} で改行)", "inputPlaceholder": "",
"inputPlaceholderWithMessages": "ダイアグラムを修正...", "inputPlaceholderWithMessages": "",
"generating": "生成中...", "generating": "",
"rateLimitRemaining": "本日の残りリクエスト回数: {{count}}", "rateLimitRemaining": "",
"role": { "role": {
"user": "あなた", "user": "",
"assistant": "AIアシスタント", "assistant": "",
"system": "システム" "system": ""
}, },
"aiBeta": "AI ベータ版", "aiBeta": "",
"label": "チャット", "label": "",
"menu": "メニュー", "menu": "",
"newChat": "新しいチャット", "newChat": "",
"deleteChat": "チャットを削除", "deleteChat": "",
"deleteMessage": "メッセージを削除", "deleteMessage": "",
"viewAsMermaid": "Mermaidで表示", "viewAsMermaid": "",
"placeholder": { "placeholder": {
"title": "ダイアグラムをデザインしよう", "title": "",
"description": "作りたいダイアグラムを説明してください。AIが生成します。", "description": "",
"hint": "" "hint": ""
}, },
"preview": "プレビュー", "preview": "",
"insert": "挿入", "insert": "",
"retry": "再試行", "retry": "",
"errors": { "errors": {
"promptTooShort": "プロンプトが短すぎます ({{min}} 文字以上)", "promptTooShort": "",
"promptTooLong": "プロンプトが長すぎます ({{max}} 文字以下)", "promptTooLong": "",
"generationFailed": "生成に失敗しました", "generationFailed": "",
"invalidDiagram": "無効なダイアグラムが生成されました。手動で編集、自動修正で再試行、または別のプロンプトをお試しください。", "invalidDiagram": "",
"fixInMermaid": "Mermaidで手動編集 →", "fixInMermaid": "",
"aiRepair": "再生成 (自動修正) →", "aiRepair": "",
"requestAborted": "リクエストが中断されました", "requestAborted": "",
"requestFailed": "リクエストに失敗しました", "requestFailed": "",
"mermaidParseError": "Mermaid構文エラー" "mermaidParseError": ""
}, },
"rateLimit": { "rateLimit": {
"messageLimit": "無料プランのAI利用上限に達しました。Excalidraw+をお試しいただくか、また明日ご利用ください。", "messageLimit": "",
"generalRateLimit": "操作が速すぎたようです。もう少し待ってから再度お試しください。", "generalRateLimit": "",
"messageLimitInputPlaceholder": "メッセージの送信上限に達しました" "messageLimitInputPlaceholder": ""
}, },
"upsellBtnLabel": "Plusにアップグレード" "upsellBtnLabel": ""
}, },
"quickSearch": { "quickSearch": {
"placeholder": "クイック検索" "placeholder": ""
}, },
"fontList": { "fontList": {
"badge": { "badge": {
"old": "" "old": ""
}, },
"sceneFonts": "このシーン内", "sceneFonts": "このシーン内",
"availableFonts": "利用可能フォント", "availableFonts": "利用可能フォント",
@@ -700,36 +680,36 @@
"hint": { "hint": {
"text": "ユーザーをクリックしてフォロー", "text": "ユーザーをクリックしてフォロー",
"followStatus": "現在このユーザーをフォローしています", "followStatus": "現在このユーザーをフォローしています",
"inCall": "ユーザーは音声通話中です", "inCall": "",
"micMuted": "ユーザーのマイクはミュート中です", "micMuted": "",
"isSpeaking": "ユーザーは発話中です" "isSpeaking": ""
} }
}, },
"commandPalette": { "commandPalette": {
"title": "コマンドパレット", "title": "",
"shortcuts": { "shortcuts": {
"select": "選択", "select": "選択",
"confirm": "確認", "confirm": "確認",
"close": "閉じる" "close": "閉じる"
}, },
"recents": "最近使ったもの", "recents": "",
"search": { "search": {
"placeholder": "メニュー、コマンドを検索して便利な機能を見つけよう", "placeholder": "",
"noMatch": "一致するコマンドはありません..." "noMatch": ""
}, },
"itemNotAvailable": "コマンドを利用できません...", "itemNotAvailable": "",
"shortcutHint": "コマンドパレットには{{shortcut}}を使用" "shortcutHint": "コマンドパレットには{{shortcut}}を使用"
}, },
"keys": { "keys": {
"ctrl": "Ctrl", "ctrl": "",
"option": "Option", "option": "",
"cmd": "Cmd", "cmd": "",
"alt": "Alt", "alt": "",
"escape": "Esc", "escape": "",
"enter": "Enter", "enter": "",
"shift": "Shift", "shift": "",
"spacebar": "スペース", "spacebar": "",
"delete": "Delete", "delete": "",
"mmb": "スクロールホイール" "mmb": ""
} }
} }
+2 -22
View File
@@ -3,10 +3,6 @@
"paste": "Qoyıw", "paste": "Qoyıw",
"pasteAsPlaintext": "Ápiwayı tekst retinde qoyıw", "pasteAsPlaintext": "Ápiwayı tekst retinde qoyıw",
"pasteCharts": "Diagrammalardı qoyıw", "pasteCharts": "Diagrammalardı qoyıw",
"chartType_bar": "",
"chartType_line": "",
"chartType_radar": "",
"chartType_plaintext": "",
"selectAll": "Barlıǵın tańlaw", "selectAll": "Barlıǵın tańlaw",
"multiSelect": "", "multiSelect": "",
"moveCanvas": "", "moveCanvas": "",
@@ -53,14 +49,7 @@
"arrowhead_crowfoot_many": "", "arrowhead_crowfoot_many": "",
"arrowhead_crowfoot_one": "", "arrowhead_crowfoot_one": "",
"arrowhead_crowfoot_one_or_many": "", "arrowhead_crowfoot_one_or_many": "",
"arrowhead_cardinality_one": "",
"arrowhead_cardinality_many": "",
"arrowhead_cardinality_one_or_many": "",
"arrowhead_cardinality_exactly_one": "",
"arrowhead_cardinality_zero_or_one": "",
"arrowhead_cardinality_zero_or_many": "",
"more_options": "", "more_options": "",
"cardinality": "",
"arrowtypes": "", "arrowtypes": "",
"arrowtype_sharp": "", "arrowtype_sharp": "",
"arrowtype_round": "", "arrowtype_round": "",
@@ -182,11 +171,7 @@
"linkToElement": "", "linkToElement": "",
"wrapSelectionInFrame": "", "wrapSelectionInFrame": "",
"tab": "", "tab": "",
"shapeSwitch": "", "shapeSwitch": ""
"preferences": "",
"preferences_toolLock": "",
"arrowBinding": "",
"midpointSnapping": ""
}, },
"elementLink": { "elementLink": {
"title": "", "title": "",
@@ -410,10 +395,6 @@
"errorDialog": { "errorDialog": {
"title": "Qátelik" "title": "Qátelik"
}, },
"progressDialog": {
"title": "",
"defaultMessage": ""
},
"exportDialog": { "exportDialog": {
"disk_title": "Diskke saqlaw", "disk_title": "Diskke saqlaw",
"disk_details": "", "disk_details": "",
@@ -635,8 +616,7 @@
"syntax": "", "syntax": "",
"preview": "", "preview": "",
"label": "", "label": "",
"inputPlaceholder": "", "inputPlaceholder": ""
"autoFixAvailable": ""
}, },
"ttd": { "ttd": {
"error": "" "error": ""
+2 -22
View File
@@ -3,10 +3,6 @@
"paste": "Senṭeḍ", "paste": "Senṭeḍ",
"pasteAsPlaintext": "", "pasteAsPlaintext": "",
"pasteCharts": "Senṭeḍ udlifen", "pasteCharts": "Senṭeḍ udlifen",
"chartType_bar": "",
"chartType_line": "",
"chartType_radar": "",
"chartType_plaintext": "",
"selectAll": "Fren akk", "selectAll": "Fren akk",
"multiSelect": "Rnu aferdis ɣer tefrayt", "multiSelect": "Rnu aferdis ɣer tefrayt",
"moveCanvas": "Smutti taɣzut n usuneɣ", "moveCanvas": "Smutti taɣzut n usuneɣ",
@@ -53,14 +49,7 @@
"arrowhead_crowfoot_many": "", "arrowhead_crowfoot_many": "",
"arrowhead_crowfoot_one": "", "arrowhead_crowfoot_one": "",
"arrowhead_crowfoot_one_or_many": "", "arrowhead_crowfoot_one_or_many": "",
"arrowhead_cardinality_one": "",
"arrowhead_cardinality_many": "",
"arrowhead_cardinality_one_or_many": "",
"arrowhead_cardinality_exactly_one": "",
"arrowhead_cardinality_zero_or_one": "",
"arrowhead_cardinality_zero_or_many": "",
"more_options": "", "more_options": "",
"cardinality": "",
"arrowtypes": "", "arrowtypes": "",
"arrowtype_sharp": "", "arrowtype_sharp": "",
"arrowtype_round": "", "arrowtype_round": "",
@@ -182,11 +171,7 @@
"linkToElement": "", "linkToElement": "",
"wrapSelectionInFrame": "", "wrapSelectionInFrame": "",
"tab": "", "tab": "",
"shapeSwitch": "", "shapeSwitch": ""
"preferences": "",
"preferences_toolLock": "",
"arrowBinding": "",
"midpointSnapping": ""
}, },
"elementLink": { "elementLink": {
"title": "", "title": "",
@@ -410,10 +395,6 @@
"errorDialog": { "errorDialog": {
"title": "Tuccḍa" "title": "Tuccḍa"
}, },
"progressDialog": {
"title": "",
"defaultMessage": ""
},
"exportDialog": { "exportDialog": {
"disk_title": "Sekles deg uḍebsi", "disk_title": "Sekles deg uḍebsi",
"disk_details": "Sekles isefka n usayes deg ufaylu ansi ara tizmireḍ ad d-tketreḍ areḍqal.", "disk_details": "Sekles isefka n usayes deg ufaylu ansi ara tizmireḍ ad d-tketreḍ areḍqal.",
@@ -635,8 +616,7 @@
"syntax": "", "syntax": "",
"preview": "", "preview": "",
"label": "", "label": "",
"inputPlaceholder": "", "inputPlaceholder": ""
"autoFixAvailable": ""
}, },
"ttd": { "ttd": {
"error": "" "error": ""
+2 -22
View File
@@ -3,10 +3,6 @@
"paste": "Қою", "paste": "Қою",
"pasteAsPlaintext": "", "pasteAsPlaintext": "",
"pasteCharts": "Диаграммаларды қою", "pasteCharts": "Диаграммаларды қою",
"chartType_bar": "",
"chartType_line": "",
"chartType_radar": "",
"chartType_plaintext": "",
"selectAll": "Бәрін таңдау", "selectAll": "Бәрін таңдау",
"multiSelect": "", "multiSelect": "",
"moveCanvas": "", "moveCanvas": "",
@@ -53,14 +49,7 @@
"arrowhead_crowfoot_many": "", "arrowhead_crowfoot_many": "",
"arrowhead_crowfoot_one": "", "arrowhead_crowfoot_one": "",
"arrowhead_crowfoot_one_or_many": "", "arrowhead_crowfoot_one_or_many": "",
"arrowhead_cardinality_one": "",
"arrowhead_cardinality_many": "",
"arrowhead_cardinality_one_or_many": "",
"arrowhead_cardinality_exactly_one": "",
"arrowhead_cardinality_zero_or_one": "",
"arrowhead_cardinality_zero_or_many": "",
"more_options": "", "more_options": "",
"cardinality": "",
"arrowtypes": "", "arrowtypes": "",
"arrowtype_sharp": "", "arrowtype_sharp": "",
"arrowtype_round": "", "arrowtype_round": "",
@@ -182,11 +171,7 @@
"linkToElement": "", "linkToElement": "",
"wrapSelectionInFrame": "", "wrapSelectionInFrame": "",
"tab": "", "tab": "",
"shapeSwitch": "", "shapeSwitch": ""
"preferences": "",
"preferences_toolLock": "",
"arrowBinding": "",
"midpointSnapping": ""
}, },
"elementLink": { "elementLink": {
"title": "", "title": "",
@@ -410,10 +395,6 @@
"errorDialog": { "errorDialog": {
"title": "Қате" "title": "Қате"
}, },
"progressDialog": {
"title": "",
"defaultMessage": ""
},
"exportDialog": { "exportDialog": {
"disk_title": "", "disk_title": "",
"disk_details": "Сахна деректерін кейін қайта импорттауға болатын файлға экспорттаңыз.", "disk_details": "Сахна деректерін кейін қайта импорттауға болатын файлға экспорттаңыз.",
@@ -635,8 +616,7 @@
"syntax": "", "syntax": "",
"preview": "", "preview": "",
"label": "", "label": "",
"inputPlaceholder": "", "inputPlaceholder": ""
"autoFixAvailable": ""
}, },
"ttd": { "ttd": {
"error": "" "error": ""
+2 -22
View File
@@ -3,10 +3,6 @@
"paste": "បិទភ្ជាប់", "paste": "បិទភ្ជាប់",
"pasteAsPlaintext": "បិទភ្ជាប់ជាអត្ថបទធម្មតា", "pasteAsPlaintext": "បិទភ្ជាប់ជាអត្ថបទធម្មតា",
"pasteCharts": "បិទភ្ជាប់តារាង", "pasteCharts": "បិទភ្ជាប់តារាង",
"chartType_bar": "",
"chartType_line": "",
"chartType_radar": "",
"chartType_plaintext": "",
"selectAll": "ជ្រើសរើស​ទាំងអស់", "selectAll": "ជ្រើសរើស​ទាំងអស់",
"multiSelect": "បន្ថែមធាតុទៅលើការជ្រើសរើស", "multiSelect": "បន្ថែមធាតុទៅលើការជ្រើសរើស",
"moveCanvas": "ផ្លាស់ទីបាវ", "moveCanvas": "ផ្លាស់ទីបាវ",
@@ -53,14 +49,7 @@
"arrowhead_crowfoot_many": "", "arrowhead_crowfoot_many": "",
"arrowhead_crowfoot_one": "", "arrowhead_crowfoot_one": "",
"arrowhead_crowfoot_one_or_many": "", "arrowhead_crowfoot_one_or_many": "",
"arrowhead_cardinality_one": "",
"arrowhead_cardinality_many": "",
"arrowhead_cardinality_one_or_many": "",
"arrowhead_cardinality_exactly_one": "",
"arrowhead_cardinality_zero_or_one": "",
"arrowhead_cardinality_zero_or_many": "",
"more_options": "", "more_options": "",
"cardinality": "",
"arrowtypes": "", "arrowtypes": "",
"arrowtype_sharp": "", "arrowtype_sharp": "",
"arrowtype_round": "", "arrowtype_round": "",
@@ -182,11 +171,7 @@
"linkToElement": "", "linkToElement": "",
"wrapSelectionInFrame": "", "wrapSelectionInFrame": "",
"tab": "", "tab": "",
"shapeSwitch": "", "shapeSwitch": ""
"preferences": "",
"preferences_toolLock": "",
"arrowBinding": "",
"midpointSnapping": ""
}, },
"elementLink": { "elementLink": {
"title": "", "title": "",
@@ -410,10 +395,6 @@
"errorDialog": { "errorDialog": {
"title": "មានកំហុស" "title": "មានកំហុស"
}, },
"progressDialog": {
"title": "",
"defaultMessage": ""
},
"exportDialog": { "exportDialog": {
"disk_title": "រក្សាទុកទៅថាស", "disk_title": "រក្សាទុកទៅថាស",
"disk_details": "នាំចេញទិន្នន័យរបស់ស៊ីនជាឯកសារដែលអ្នកអាចនាំចូលនៅពេលក្រោយ។", "disk_details": "នាំចេញទិន្នន័យរបស់ស៊ីនជាឯកសារដែលអ្នកអាចនាំចូលនៅពេលក្រោយ។",
@@ -635,8 +616,7 @@
"syntax": "", "syntax": "",
"preview": "", "preview": "",
"label": "", "label": "",
"inputPlaceholder": "", "inputPlaceholder": ""
"autoFixAvailable": ""
}, },
"ttd": { "ttd": {
"error": "" "error": ""
+2 -22
View File
@@ -3,10 +3,6 @@
"paste": "붙여넣기", "paste": "붙여넣기",
"pasteAsPlaintext": "일반 텍스트로 붙여넣기", "pasteAsPlaintext": "일반 텍스트로 붙여넣기",
"pasteCharts": "차트 붙여넣기", "pasteCharts": "차트 붙여넣기",
"chartType_bar": "",
"chartType_line": "",
"chartType_radar": "",
"chartType_plaintext": "",
"selectAll": "전체 선택", "selectAll": "전체 선택",
"multiSelect": "선택 영역에 추가하기", "multiSelect": "선택 영역에 추가하기",
"moveCanvas": "캔버스 이동", "moveCanvas": "캔버스 이동",
@@ -53,14 +49,7 @@
"arrowhead_crowfoot_many": "", "arrowhead_crowfoot_many": "",
"arrowhead_crowfoot_one": "", "arrowhead_crowfoot_one": "",
"arrowhead_crowfoot_one_or_many": "", "arrowhead_crowfoot_one_or_many": "",
"arrowhead_cardinality_one": "",
"arrowhead_cardinality_many": "",
"arrowhead_cardinality_one_or_many": "",
"arrowhead_cardinality_exactly_one": "",
"arrowhead_cardinality_zero_or_one": "",
"arrowhead_cardinality_zero_or_many": "",
"more_options": "", "more_options": "",
"cardinality": "",
"arrowtypes": "화살표 모양", "arrowtypes": "화살표 모양",
"arrowtype_sharp": "뾰족한 화살표", "arrowtype_sharp": "뾰족한 화살표",
"arrowtype_round": "곡선 화살표", "arrowtype_round": "곡선 화살표",
@@ -182,11 +171,7 @@
"linkToElement": "", "linkToElement": "",
"wrapSelectionInFrame": "", "wrapSelectionInFrame": "",
"tab": "", "tab": "",
"shapeSwitch": "", "shapeSwitch": ""
"preferences": "",
"preferences_toolLock": "",
"arrowBinding": "",
"midpointSnapping": ""
}, },
"elementLink": { "elementLink": {
"title": "", "title": "",
@@ -410,10 +395,6 @@
"errorDialog": { "errorDialog": {
"title": "오류" "title": "오류"
}, },
"progressDialog": {
"title": "",
"defaultMessage": ""
},
"exportDialog": { "exportDialog": {
"disk_title": "디스크에 저장", "disk_title": "디스크에 저장",
"disk_details": "나중에 다시 불러올 수 있도록 화면 데이터를 내보냅니다.", "disk_details": "나중에 다시 불러올 수 있도록 화면 데이터를 내보냅니다.",
@@ -635,8 +616,7 @@
"syntax": "", "syntax": "",
"preview": "", "preview": "",
"label": "", "label": "",
"inputPlaceholder": "", "inputPlaceholder": ""
"autoFixAvailable": ""
}, },
"ttd": { "ttd": {
"error": "" "error": ""
+2 -22
View File
@@ -3,10 +3,6 @@
"paste": "دانانەوە", "paste": "دانانەوە",
"pasteAsPlaintext": "دایبنێ وەک دەقی سادە", "pasteAsPlaintext": "دایبنێ وەک دەقی سادە",
"pasteCharts": "دانانەوەی خشتەکان", "pasteCharts": "دانانەوەی خشتەکان",
"chartType_bar": "",
"chartType_line": "",
"chartType_radar": "",
"chartType_plaintext": "",
"selectAll": "دیاریکردنی هەموو", "selectAll": "دیاریکردنی هەموو",
"multiSelect": "زیادکردنی بۆ دیاریکراوەکان", "multiSelect": "زیادکردنی بۆ دیاریکراوەکان",
"moveCanvas": "تابلۆ بجوڵێنە", "moveCanvas": "تابلۆ بجوڵێنە",
@@ -53,14 +49,7 @@
"arrowhead_crowfoot_many": "", "arrowhead_crowfoot_many": "",
"arrowhead_crowfoot_one": "", "arrowhead_crowfoot_one": "",
"arrowhead_crowfoot_one_or_many": "", "arrowhead_crowfoot_one_or_many": "",
"arrowhead_cardinality_one": "",
"arrowhead_cardinality_many": "",
"arrowhead_cardinality_one_or_many": "",
"arrowhead_cardinality_exactly_one": "",
"arrowhead_cardinality_zero_or_one": "",
"arrowhead_cardinality_zero_or_many": "",
"more_options": "", "more_options": "",
"cardinality": "",
"arrowtypes": "", "arrowtypes": "",
"arrowtype_sharp": "", "arrowtype_sharp": "",
"arrowtype_round": "", "arrowtype_round": "",
@@ -182,11 +171,7 @@
"linkToElement": "", "linkToElement": "",
"wrapSelectionInFrame": "", "wrapSelectionInFrame": "",
"tab": "", "tab": "",
"shapeSwitch": "", "shapeSwitch": ""
"preferences": "",
"preferences_toolLock": "",
"arrowBinding": "",
"midpointSnapping": ""
}, },
"elementLink": { "elementLink": {
"title": "", "title": "",
@@ -410,10 +395,6 @@
"errorDialog": { "errorDialog": {
"title": "هه‌ڵه‌ ڕوویدا" "title": "هه‌ڵه‌ ڕوویدا"
}, },
"progressDialog": {
"title": "",
"defaultMessage": ""
},
"exportDialog": { "exportDialog": {
"disk_title": "پاشەکەوت بکە لە دیسک", "disk_title": "پاشەکەوت بکە لە دیسک",
"disk_details": "هەناردەکردنی داتای دیمەنەکە بۆ فایلێک کە دواتر دەتوانیت لێی هاوردە بکەیت.", "disk_details": "هەناردەکردنی داتای دیمەنەکە بۆ فایلێک کە دواتر دەتوانیت لێی هاوردە بکەیت.",
@@ -635,8 +616,7 @@
"syntax": "", "syntax": "",
"preview": "", "preview": "",
"label": "", "label": "",
"inputPlaceholder": "", "inputPlaceholder": ""
"autoFixAvailable": ""
}, },
"ttd": { "ttd": {
"error": "" "error": ""
+2 -22
View File
@@ -3,10 +3,6 @@
"paste": "Įklijuoti", "paste": "Įklijuoti",
"pasteAsPlaintext": "Įklijuoti kaip paprastą tekstą", "pasteAsPlaintext": "Įklijuoti kaip paprastą tekstą",
"pasteCharts": "Įklijuoti diagramas", "pasteCharts": "Įklijuoti diagramas",
"chartType_bar": "",
"chartType_line": "",
"chartType_radar": "",
"chartType_plaintext": "",
"selectAll": "Pažymėti viską", "selectAll": "Pažymėti viską",
"multiSelect": "Pridėkite elementą prie pasirinktų", "multiSelect": "Pridėkite elementą prie pasirinktų",
"moveCanvas": "Judinti drobę", "moveCanvas": "Judinti drobę",
@@ -53,14 +49,7 @@
"arrowhead_crowfoot_many": "", "arrowhead_crowfoot_many": "",
"arrowhead_crowfoot_one": "", "arrowhead_crowfoot_one": "",
"arrowhead_crowfoot_one_or_many": "", "arrowhead_crowfoot_one_or_many": "",
"arrowhead_cardinality_one": "",
"arrowhead_cardinality_many": "",
"arrowhead_cardinality_one_or_many": "",
"arrowhead_cardinality_exactly_one": "",
"arrowhead_cardinality_zero_or_one": "",
"arrowhead_cardinality_zero_or_many": "",
"more_options": "", "more_options": "",
"cardinality": "",
"arrowtypes": "", "arrowtypes": "",
"arrowtype_sharp": "", "arrowtype_sharp": "",
"arrowtype_round": "", "arrowtype_round": "",
@@ -182,11 +171,7 @@
"linkToElement": "", "linkToElement": "",
"wrapSelectionInFrame": "", "wrapSelectionInFrame": "",
"tab": "", "tab": "",
"shapeSwitch": "", "shapeSwitch": ""
"preferences": "",
"preferences_toolLock": "",
"arrowBinding": "",
"midpointSnapping": ""
}, },
"elementLink": { "elementLink": {
"title": "", "title": "",
@@ -410,10 +395,6 @@
"errorDialog": { "errorDialog": {
"title": "Klaida" "title": "Klaida"
}, },
"progressDialog": {
"title": "",
"defaultMessage": ""
},
"exportDialog": { "exportDialog": {
"disk_title": "Įrašyti į diską", "disk_title": "Įrašyti į diską",
"disk_details": "", "disk_details": "",
@@ -635,8 +616,7 @@
"syntax": "", "syntax": "",
"preview": "", "preview": "",
"label": "", "label": "",
"inputPlaceholder": "", "inputPlaceholder": ""
"autoFixAvailable": ""
}, },
"ttd": { "ttd": {
"error": "" "error": ""
+2 -22
View File
@@ -3,10 +3,6 @@
"paste": "Ielīmēt", "paste": "Ielīmēt",
"pasteAsPlaintext": "Ielīmēt kā vienkāršu tekstu", "pasteAsPlaintext": "Ielīmēt kā vienkāršu tekstu",
"pasteCharts": "Ielīmēt grafikus", "pasteCharts": "Ielīmēt grafikus",
"chartType_bar": "",
"chartType_line": "",
"chartType_radar": "",
"chartType_plaintext": "",
"selectAll": "Atlasīt visu", "selectAll": "Atlasīt visu",
"multiSelect": "Pievienot elementu atlasei", "multiSelect": "Pievienot elementu atlasei",
"moveCanvas": "Pārvietot tāfeli", "moveCanvas": "Pārvietot tāfeli",
@@ -53,14 +49,7 @@
"arrowhead_crowfoot_many": "", "arrowhead_crowfoot_many": "",
"arrowhead_crowfoot_one": "", "arrowhead_crowfoot_one": "",
"arrowhead_crowfoot_one_or_many": "", "arrowhead_crowfoot_one_or_many": "",
"arrowhead_cardinality_one": "",
"arrowhead_cardinality_many": "",
"arrowhead_cardinality_one_or_many": "",
"arrowhead_cardinality_exactly_one": "",
"arrowhead_cardinality_zero_or_one": "",
"arrowhead_cardinality_zero_or_many": "",
"more_options": "", "more_options": "",
"cardinality": "",
"arrowtypes": "", "arrowtypes": "",
"arrowtype_sharp": "", "arrowtype_sharp": "",
"arrowtype_round": "", "arrowtype_round": "",
@@ -182,11 +171,7 @@
"linkToElement": "", "linkToElement": "",
"wrapSelectionInFrame": "", "wrapSelectionInFrame": "",
"tab": "", "tab": "",
"shapeSwitch": "", "shapeSwitch": ""
"preferences": "",
"preferences_toolLock": "",
"arrowBinding": "",
"midpointSnapping": ""
}, },
"elementLink": { "elementLink": {
"title": "", "title": "",
@@ -410,10 +395,6 @@
"errorDialog": { "errorDialog": {
"title": "Kļūda" "title": "Kļūda"
}, },
"progressDialog": {
"title": "",
"defaultMessage": ""
},
"exportDialog": { "exportDialog": {
"disk_title": "Saglabāt diskā", "disk_title": "Saglabāt diskā",
"disk_details": "Eksportēt ainas datus datnē, ko vēlāk varēsiet importēt.", "disk_details": "Eksportēt ainas datus datnē, ko vēlāk varēsiet importēt.",
@@ -635,8 +616,7 @@
"syntax": "", "syntax": "",
"preview": "", "preview": "",
"label": "", "label": "",
"inputPlaceholder": "", "inputPlaceholder": ""
"autoFixAvailable": ""
}, },
"ttd": { "ttd": {
"error": "" "error": ""
+3 -23
View File
@@ -3,10 +3,6 @@
"paste": "चिटकवा", "paste": "चिटकवा",
"pasteAsPlaintext": "साधा मजकूर च्या रुपात पेस्ट करा", "pasteAsPlaintext": "साधा मजकूर च्या रुपात पेस्ट करा",
"pasteCharts": "चार्ट चिकटवा", "pasteCharts": "चार्ट चिकटवा",
"chartType_bar": "",
"chartType_line": "",
"chartType_radar": "",
"chartType_plaintext": "",
"selectAll": "समस्त निवडा", "selectAll": "समस्त निवडा",
"multiSelect": "निवडित तत्व जोडा", "multiSelect": "निवडित तत्व जोडा",
"moveCanvas": "पटल हलवा", "moveCanvas": "पटल हलवा",
@@ -53,14 +49,7 @@
"arrowhead_crowfoot_many": "चिमणि पाय (अनेक)", "arrowhead_crowfoot_many": "चिमणि पाय (अनेक)",
"arrowhead_crowfoot_one": "चिमणि पाय (एक)", "arrowhead_crowfoot_one": "चिमणि पाय (एक)",
"arrowhead_crowfoot_one_or_many": "चिमणि पाय (एक अथवा अनेक)", "arrowhead_crowfoot_one_or_many": "चिमणि पाय (एक अथवा अनेक)",
"arrowhead_cardinality_one": "",
"arrowhead_cardinality_many": "",
"arrowhead_cardinality_one_or_many": "",
"arrowhead_cardinality_exactly_one": "",
"arrowhead_cardinality_zero_or_one": "",
"arrowhead_cardinality_zero_or_many": "",
"more_options": "आणिक विकल्प", "more_options": "आणिक विकल्प",
"cardinality": "",
"arrowtypes": "बाणाचे प्रकार", "arrowtypes": "बाणाचे प्रकार",
"arrowtype_sharp": "तीक्ष्ण तीर", "arrowtype_sharp": "तीक्ष्ण तीर",
"arrowtype_round": "वक्राकार तीर", "arrowtype_round": "वक्राकार तीर",
@@ -182,11 +171,7 @@
"linkToElement": "वस्तू ह्याचा दुवा", "linkToElement": "वस्तू ह्याचा दुवा",
"wrapSelectionInFrame": "चौकटित निवडलेले गुंडाळा", "wrapSelectionInFrame": "चौकटित निवडलेले गुंडाळा",
"tab": "", "tab": "",
"shapeSwitch": "", "shapeSwitch": ""
"preferences": "",
"preferences_toolLock": "",
"arrowBinding": "",
"midpointSnapping": ""
}, },
"elementLink": { "elementLink": {
"title": "वस्तू ह्याचा दुवा", "title": "वस्तू ह्याचा दुवा",
@@ -410,10 +395,6 @@
"errorDialog": { "errorDialog": {
"title": "त्रुटि" "title": "त्रुटि"
}, },
"progressDialog": {
"title": "",
"defaultMessage": ""
},
"exportDialog": { "exportDialog": {
"disk_title": "डिस्क मधे जतन करा", "disk_title": "डिस्क मधे जतन करा",
"disk_details": "सीन डेटा बाहेर एक फ़ाइल मधे जतन करा, त्या फ़ाइल मधुम तो डेटा नंतर परत आणु शकता.", "disk_details": "सीन डेटा बाहेर एक फ़ाइल मधे जतन करा, त्या फ़ाइल मधुम तो डेटा नंतर परत आणु शकता.",
@@ -631,12 +612,11 @@
"mermaid": { "mermaid": {
"title": "मर्मेड पासून एक्सकाली मधे", "title": "मर्मेड पासून एक्सकाली मधे",
"button": "शिरवा", "button": "शिरवा",
"description": "", "description": "सध्या फक्त <flowchartLink> प्रवाह चित्र (फ़्लो चार्ट) </flowchartLink> आणि <sequenceLink> क्रम चित्र (सिकवेंस ड़ायग्राम) </sequenceLink> करता येतात. बाक़ीचे चित्र प्रकार एक्सकाली चित्र पद्धति नी चित्रित होतील.",
"syntax": "मर्मेड संरचना नियम", "syntax": "मर्मेड संरचना नियम",
"preview": "पूर्वावलोकन", "preview": "पूर्वावलोकन",
"label": "", "label": "",
"inputPlaceholder": "", "inputPlaceholder": ""
"autoFixAvailable": ""
}, },
"ttd": { "ttd": {
"error": "" "error": ""
+2 -22
View File
@@ -3,10 +3,6 @@
"paste": "ထား", "paste": "ထား",
"pasteAsPlaintext": "", "pasteAsPlaintext": "",
"pasteCharts": "", "pasteCharts": "",
"chartType_bar": "",
"chartType_line": "",
"chartType_radar": "",
"chartType_plaintext": "",
"selectAll": "အကုန်ရွေး", "selectAll": "အကုန်ရွေး",
"multiSelect": "ရွေးထားသည့်ထဲပုံထည့်", "multiSelect": "ရွေးထားသည့်ထဲပုံထည့်",
"moveCanvas": "ကားချပ်ရွှေ့", "moveCanvas": "ကားချပ်ရွှေ့",
@@ -53,14 +49,7 @@
"arrowhead_crowfoot_many": "", "arrowhead_crowfoot_many": "",
"arrowhead_crowfoot_one": "", "arrowhead_crowfoot_one": "",
"arrowhead_crowfoot_one_or_many": "", "arrowhead_crowfoot_one_or_many": "",
"arrowhead_cardinality_one": "",
"arrowhead_cardinality_many": "",
"arrowhead_cardinality_one_or_many": "",
"arrowhead_cardinality_exactly_one": "",
"arrowhead_cardinality_zero_or_one": "",
"arrowhead_cardinality_zero_or_many": "",
"more_options": "", "more_options": "",
"cardinality": "",
"arrowtypes": "", "arrowtypes": "",
"arrowtype_sharp": "", "arrowtype_sharp": "",
"arrowtype_round": "", "arrowtype_round": "",
@@ -182,11 +171,7 @@
"linkToElement": "", "linkToElement": "",
"wrapSelectionInFrame": "", "wrapSelectionInFrame": "",
"tab": "", "tab": "",
"shapeSwitch": "", "shapeSwitch": ""
"preferences": "",
"preferences_toolLock": "",
"arrowBinding": "",
"midpointSnapping": ""
}, },
"elementLink": { "elementLink": {
"title": "", "title": "",
@@ -410,10 +395,6 @@
"errorDialog": { "errorDialog": {
"title": "ချို့ယွင်းချက်" "title": "ချို့ယွင်းချက်"
}, },
"progressDialog": {
"title": "",
"defaultMessage": ""
},
"exportDialog": { "exportDialog": {
"disk_title": "", "disk_title": "",
"disk_details": "", "disk_details": "",
@@ -635,8 +616,7 @@
"syntax": "", "syntax": "",
"preview": "", "preview": "",
"label": "", "label": "",
"inputPlaceholder": "", "inputPlaceholder": ""
"autoFixAvailable": ""
}, },
"ttd": { "ttd": {
"error": "" "error": ""
+3 -23
View File
@@ -3,10 +3,6 @@
"paste": "Lim inn", "paste": "Lim inn",
"pasteAsPlaintext": "Lim inn som klartekst", "pasteAsPlaintext": "Lim inn som klartekst",
"pasteCharts": "Lim inn diagrammer", "pasteCharts": "Lim inn diagrammer",
"chartType_bar": "",
"chartType_line": "",
"chartType_radar": "",
"chartType_plaintext": "",
"selectAll": "Velg alt", "selectAll": "Velg alt",
"multiSelect": "Legg til element i utvalg", "multiSelect": "Legg til element i utvalg",
"moveCanvas": "Flytt lerretet", "moveCanvas": "Flytt lerretet",
@@ -53,14 +49,7 @@
"arrowhead_crowfoot_many": "Kråkefot (mange)", "arrowhead_crowfoot_many": "Kråkefot (mange)",
"arrowhead_crowfoot_one": "Kråkefot (én)", "arrowhead_crowfoot_one": "Kråkefot (én)",
"arrowhead_crowfoot_one_or_many": "Kråkefot (én eller mange)", "arrowhead_crowfoot_one_or_many": "Kråkefot (én eller mange)",
"arrowhead_cardinality_one": "",
"arrowhead_cardinality_many": "",
"arrowhead_cardinality_one_or_many": "",
"arrowhead_cardinality_exactly_one": "",
"arrowhead_cardinality_zero_or_one": "",
"arrowhead_cardinality_zero_or_many": "",
"more_options": "Flere alternativer", "more_options": "Flere alternativer",
"cardinality": "",
"arrowtypes": "Type pil", "arrowtypes": "Type pil",
"arrowtype_sharp": "Skarp pil", "arrowtype_sharp": "Skarp pil",
"arrowtype_round": "Buet pil", "arrowtype_round": "Buet pil",
@@ -182,11 +171,7 @@
"linkToElement": "Lenke til objekt", "linkToElement": "Lenke til objekt",
"wrapSelectionInFrame": "Brekk om utvalg i ramme", "wrapSelectionInFrame": "Brekk om utvalg i ramme",
"tab": "", "tab": "",
"shapeSwitch": "", "shapeSwitch": ""
"preferences": "",
"preferences_toolLock": "",
"arrowBinding": "",
"midpointSnapping": ""
}, },
"elementLink": { "elementLink": {
"title": "Lenke til objekt", "title": "Lenke til objekt",
@@ -410,10 +395,6 @@
"errorDialog": { "errorDialog": {
"title": "Feil" "title": "Feil"
}, },
"progressDialog": {
"title": "",
"defaultMessage": ""
},
"exportDialog": { "exportDialog": {
"disk_title": "Lagre til disk", "disk_title": "Lagre til disk",
"disk_details": "Eksporter scene-dataene til en fil som du kan importere fra senere.", "disk_details": "Eksporter scene-dataene til en fil som du kan importere fra senere.",
@@ -631,12 +612,11 @@
"mermaid": { "mermaid": {
"title": "Mermaid til Excalidraw", "title": "Mermaid til Excalidraw",
"button": "Sett inn", "button": "Sett inn",
"description": "", "description": "Foreløpig er bare <flowchartLink>Flowchart</flowchartLink>-,<sequenceLink> Sequence</sequenceLink>- og <classLink>klasse </classLink>-diagrammer støttet. De andre typene vil bli gjengitt som bilde i Excalidraw.",
"syntax": "Mermaid-syntaks", "syntax": "Mermaid-syntaks",
"preview": "Forhåndsvisning", "preview": "Forhåndsvisning",
"label": "", "label": "",
"inputPlaceholder": "", "inputPlaceholder": ""
"autoFixAvailable": ""
}, },
"ttd": { "ttd": {
"error": "" "error": ""
+9 -29
View File
@@ -3,10 +3,6 @@
"paste": "Plakken", "paste": "Plakken",
"pasteAsPlaintext": "Plakken als platte tekst", "pasteAsPlaintext": "Plakken als platte tekst",
"pasteCharts": "Grafieken plakken", "pasteCharts": "Grafieken plakken",
"chartType_bar": "",
"chartType_line": "",
"chartType_radar": "",
"chartType_plaintext": "",
"selectAll": "Alles selecteren", "selectAll": "Alles selecteren",
"multiSelect": "Voeg element toe aan selectie", "multiSelect": "Voeg element toe aan selectie",
"moveCanvas": "Canvas verplaatsen", "moveCanvas": "Canvas verplaatsen",
@@ -53,14 +49,7 @@
"arrowhead_crowfoot_many": "Kraaienpoot (veel)", "arrowhead_crowfoot_many": "Kraaienpoot (veel)",
"arrowhead_crowfoot_one": "Kraaienpoot (enkel)", "arrowhead_crowfoot_one": "Kraaienpoot (enkel)",
"arrowhead_crowfoot_one_or_many": "Kraaienpoot (enkel of veel)", "arrowhead_crowfoot_one_or_many": "Kraaienpoot (enkel of veel)",
"arrowhead_cardinality_one": "",
"arrowhead_cardinality_many": "",
"arrowhead_cardinality_one_or_many": "",
"arrowhead_cardinality_exactly_one": "",
"arrowhead_cardinality_zero_or_one": "",
"arrowhead_cardinality_zero_or_many": "",
"more_options": "Meer opties", "more_options": "Meer opties",
"cardinality": "",
"arrowtypes": "Pijl type", "arrowtypes": "Pijl type",
"arrowtype_sharp": "Scherpe pijl", "arrowtype_sharp": "Scherpe pijl",
"arrowtype_round": "Gebogen pijl", "arrowtype_round": "Gebogen pijl",
@@ -182,11 +171,7 @@
"linkToElement": "Link naar object", "linkToElement": "Link naar object",
"wrapSelectionInFrame": "Selectie omslaan in frame", "wrapSelectionInFrame": "Selectie omslaan in frame",
"tab": "Tab", "tab": "Tab",
"shapeSwitch": "Verander vorm", "shapeSwitch": "Verander vorm"
"preferences": "Voorkeuren",
"preferences_toolLock": "Tool vergrendelen",
"arrowBinding": "",
"midpointSnapping": ""
}, },
"elementLink": { "elementLink": {
"title": "Link naar object", "title": "Link naar object",
@@ -410,10 +395,6 @@
"errorDialog": { "errorDialog": {
"title": "Fout" "title": "Fout"
}, },
"progressDialog": {
"title": "",
"defaultMessage": ""
},
"exportDialog": { "exportDialog": {
"disk_title": "Opslaan op schijf", "disk_title": "Opslaan op schijf",
"disk_details": "De scènegegevens exporteren naar een bestand waaruit u later kunt importeren.", "disk_details": "De scènegegevens exporteren naar een bestand waaruit u later kunt importeren.",
@@ -576,9 +557,9 @@
}, },
"welcomeScreen": { "welcomeScreen": {
"app": { "app": {
"center_heading": "Je tekeningen worden bewaard in de opslag van je browser.", "center_heading": "",
"center_heading_line2": "Browser opslag kan onverwacht gewist worden.", "center_heading_line2": "",
"center_heading_line3": "Sla je werk regelmatig op in een bestand om te voorkomen dat je het kwijtraakt.", "center_heading_line3": "",
"center_heading_plus": "Wil je in plaats daarvan naar Excalidraw+ gaan?", "center_heading_plus": "Wil je in plaats daarvan naar Excalidraw+ gaan?",
"menuHint": "Exporteren, voorkeuren en meer, ..." "menuHint": "Exporteren, voorkeuren en meer, ..."
}, },
@@ -631,12 +612,11 @@
"mermaid": { "mermaid": {
"title": "Mermaid naar Excalidraw", "title": "Mermaid naar Excalidraw",
"button": "Invoegen", "button": "Invoegen",
"description": "", "description": "Momenteel worden alleen <flowchartLink>Flowchart</flowchartLink>-, <sequenceLink>Sequence</sequenceLink>- en <classLink>Class</classLink>-diagrammen ondersteund. De andere types worden als afbeelding weergegeven in Excalidraw.",
"syntax": "Mermaid Syntaxis", "syntax": "Mermaid Syntaxis",
"preview": "Voorbeeld", "preview": "Voorbeeld",
"label": "Mermaid", "label": "Mermaid",
"inputPlaceholder": "Noteer Mermaid diagram omschrijving hier...", "inputPlaceholder": "Noteer Mermaid diagram omschrijving hier..."
"autoFixAvailable": ""
}, },
"ttd": { "ttd": {
"error": "Fout!" "error": "Fout!"
@@ -644,7 +624,7 @@
"chat": { "chat": {
"inputPlaceholder": "Begin je diagram idee hier in te typen... ({{shortcut}} voor een nieuwe lijn)", "inputPlaceholder": "Begin je diagram idee hier in te typen... ({{shortcut}} voor een nieuwe lijn)",
"inputPlaceholderWithMessages": "Ga door met het verfijnen van je diagram...", "inputPlaceholderWithMessages": "Ga door met het verfijnen van je diagram...",
"generating": "Genereren...", "generating": "",
"rateLimitRemaining": "{{count}} verzoeken over vandaag", "rateLimitRemaining": "{{count}} verzoeken over vandaag",
"role": { "role": {
"user": "Jij", "user": "Jij",
@@ -661,7 +641,7 @@
"placeholder": { "placeholder": {
"title": "Laten we jouw diagram ontwerpen", "title": "Laten we jouw diagram ontwerpen",
"description": "Beschrijf het diagram dat je wilt aanmaken, en we genereren het voor je.", "description": "Beschrijf het diagram dat je wilt aanmaken, en we genereren het voor je.",
"hint": "" "hint": "Op dit moment kennen we Flowchart, Sequence, en Class diagrammen."
}, },
"preview": "Voorbeeld", "preview": "Voorbeeld",
"insert": "Invoegen", "insert": "Invoegen",
@@ -675,7 +655,7 @@
"aiRepair": "Opnieuw genereren (automatisch repareren) →", "aiRepair": "Opnieuw genereren (automatisch repareren) →",
"requestAborted": "Verzoek gestopt", "requestAborted": "Verzoek gestopt",
"requestFailed": "Verzoek mislukt", "requestFailed": "Verzoek mislukt",
"mermaidParseError": "Mermaid syntax fout" "mermaidParseError": ""
}, },
"rateLimit": { "rateLimit": {
"messageLimit": "Je hebt je AI limiet bereikt op het gratis abonnement. Probeer Excalidraw+ uit voor meer of kom morgen terug.", "messageLimit": "Je hebt je AI limiet bereikt op het gratis abonnement. Probeer Excalidraw+ uit voor meer of kom morgen terug.",
+2 -22
View File
@@ -3,10 +3,6 @@
"paste": "Lim inn", "paste": "Lim inn",
"pasteAsPlaintext": "", "pasteAsPlaintext": "",
"pasteCharts": "Lim inn diagram", "pasteCharts": "Lim inn diagram",
"chartType_bar": "",
"chartType_line": "",
"chartType_radar": "",
"chartType_plaintext": "",
"selectAll": "Vel alt", "selectAll": "Vel alt",
"multiSelect": "Legg til element i utval", "multiSelect": "Legg til element i utval",
"moveCanvas": "Flytt lerretet", "moveCanvas": "Flytt lerretet",
@@ -53,14 +49,7 @@
"arrowhead_crowfoot_many": "", "arrowhead_crowfoot_many": "",
"arrowhead_crowfoot_one": "", "arrowhead_crowfoot_one": "",
"arrowhead_crowfoot_one_or_many": "", "arrowhead_crowfoot_one_or_many": "",
"arrowhead_cardinality_one": "",
"arrowhead_cardinality_many": "",
"arrowhead_cardinality_one_or_many": "",
"arrowhead_cardinality_exactly_one": "",
"arrowhead_cardinality_zero_or_one": "",
"arrowhead_cardinality_zero_or_many": "",
"more_options": "", "more_options": "",
"cardinality": "",
"arrowtypes": "", "arrowtypes": "",
"arrowtype_sharp": "", "arrowtype_sharp": "",
"arrowtype_round": "", "arrowtype_round": "",
@@ -182,11 +171,7 @@
"linkToElement": "", "linkToElement": "",
"wrapSelectionInFrame": "", "wrapSelectionInFrame": "",
"tab": "", "tab": "",
"shapeSwitch": "", "shapeSwitch": ""
"preferences": "",
"preferences_toolLock": "",
"arrowBinding": "",
"midpointSnapping": ""
}, },
"elementLink": { "elementLink": {
"title": "", "title": "",
@@ -410,10 +395,6 @@
"errorDialog": { "errorDialog": {
"title": "Feil" "title": "Feil"
}, },
"progressDialog": {
"title": "",
"defaultMessage": ""
},
"exportDialog": { "exportDialog": {
"disk_title": "Lagre til disk", "disk_title": "Lagre til disk",
"disk_details": "Eksporter scenedataa til ei fil du kan importere seinare.", "disk_details": "Eksporter scenedataa til ei fil du kan importere seinare.",
@@ -635,8 +616,7 @@
"syntax": "", "syntax": "",
"preview": "", "preview": "",
"label": "", "label": "",
"inputPlaceholder": "", "inputPlaceholder": ""
"autoFixAvailable": ""
}, },
"ttd": { "ttd": {
"error": "" "error": ""
+3 -23
View File
@@ -3,10 +3,6 @@
"paste": "Pegar", "paste": "Pegar",
"pasteAsPlaintext": "Pegar en tèxt brut", "pasteAsPlaintext": "Pegar en tèxt brut",
"pasteCharts": "Pegar los grafics", "pasteCharts": "Pegar los grafics",
"chartType_bar": "",
"chartType_line": "",
"chartType_radar": "",
"chartType_plaintext": "",
"selectAll": "Tot seleccionar", "selectAll": "Tot seleccionar",
"multiSelect": "Apondre un element a la seleccion", "multiSelect": "Apondre un element a la seleccion",
"moveCanvas": "Desplaçar lo canabàs", "moveCanvas": "Desplaçar lo canabàs",
@@ -53,14 +49,7 @@
"arrowhead_crowfoot_many": "", "arrowhead_crowfoot_many": "",
"arrowhead_crowfoot_one": "", "arrowhead_crowfoot_one": "",
"arrowhead_crowfoot_one_or_many": "", "arrowhead_crowfoot_one_or_many": "",
"arrowhead_cardinality_one": "",
"arrowhead_cardinality_many": "",
"arrowhead_cardinality_one_or_many": "",
"arrowhead_cardinality_exactly_one": "",
"arrowhead_cardinality_zero_or_one": "",
"arrowhead_cardinality_zero_or_many": "",
"more_options": "", "more_options": "",
"cardinality": "",
"arrowtypes": "", "arrowtypes": "",
"arrowtype_sharp": "", "arrowtype_sharp": "",
"arrowtype_round": "", "arrowtype_round": "",
@@ -182,11 +171,7 @@
"linkToElement": "Ligam cap a lobjècte", "linkToElement": "Ligam cap a lobjècte",
"wrapSelectionInFrame": "", "wrapSelectionInFrame": "",
"tab": "Onglet", "tab": "Onglet",
"shapeSwitch": "", "shapeSwitch": ""
"preferences": "",
"preferences_toolLock": "",
"arrowBinding": "",
"midpointSnapping": ""
}, },
"elementLink": { "elementLink": {
"title": "", "title": "",
@@ -410,10 +395,6 @@
"errorDialog": { "errorDialog": {
"title": "Error" "title": "Error"
}, },
"progressDialog": {
"title": "",
"defaultMessage": ""
},
"exportDialog": { "exportDialog": {
"disk_title": "Salvar al disc", "disk_title": "Salvar al disc",
"disk_details": "Exportar las donadas de la scèna cap a un fichièr que podètz importar mai tard.", "disk_details": "Exportar las donadas de la scèna cap a un fichièr que podètz importar mai tard.",
@@ -631,12 +612,11 @@
"mermaid": { "mermaid": {
"title": "De Mermaid cap a Excalidraw", "title": "De Mermaid cap a Excalidraw",
"button": "Inserir", "button": "Inserir",
"description": "", "description": "Actualament, sonque los diagramas <flowchartLink>logics</flowchartLink>,<sequenceLink> de sequéncia</sequenceLink> e <classLink>de classa </classLink>son preses en carga. Los autres tipes seràn afichats coma imatge dins Excalidraw.",
"syntax": "Sintaxi Mermaid", "syntax": "Sintaxi Mermaid",
"preview": "Apercebut", "preview": "Apercebut",
"label": "", "label": "",
"inputPlaceholder": "", "inputPlaceholder": ""
"autoFixAvailable": ""
}, },
"ttd": { "ttd": {
"error": "" "error": ""
+2 -22
View File
@@ -3,10 +3,6 @@
"paste": "ਪੇਸਟ ਕਰੋ", "paste": "ਪੇਸਟ ਕਰੋ",
"pasteAsPlaintext": "ਸਾਦੇ ਪਾਠ ਵਜੋਂ ਪੇਸਟ ਕਰੋ", "pasteAsPlaintext": "ਸਾਦੇ ਪਾਠ ਵਜੋਂ ਪੇਸਟ ਕਰੋ",
"pasteCharts": "ਚਾਰਟ ਪੇਸਟ ਕਰੋ", "pasteCharts": "ਚਾਰਟ ਪੇਸਟ ਕਰੋ",
"chartType_bar": "",
"chartType_line": "",
"chartType_radar": "",
"chartType_plaintext": "",
"selectAll": "ਸਾਰੇ ਚੁਣੋ", "selectAll": "ਸਾਰੇ ਚੁਣੋ",
"multiSelect": "ਐਲੀਮੈਂਟ ਨੂੰ ਚੋਣ ਵਿੱਚ ਜੋੜੋ", "multiSelect": "ਐਲੀਮੈਂਟ ਨੂੰ ਚੋਣ ਵਿੱਚ ਜੋੜੋ",
"moveCanvas": "ਕੈਨਵਸ ਹਿਲਾਓ", "moveCanvas": "ਕੈਨਵਸ ਹਿਲਾਓ",
@@ -53,14 +49,7 @@
"arrowhead_crowfoot_many": "", "arrowhead_crowfoot_many": "",
"arrowhead_crowfoot_one": "", "arrowhead_crowfoot_one": "",
"arrowhead_crowfoot_one_or_many": "", "arrowhead_crowfoot_one_or_many": "",
"arrowhead_cardinality_one": "",
"arrowhead_cardinality_many": "",
"arrowhead_cardinality_one_or_many": "",
"arrowhead_cardinality_exactly_one": "",
"arrowhead_cardinality_zero_or_one": "",
"arrowhead_cardinality_zero_or_many": "",
"more_options": "", "more_options": "",
"cardinality": "",
"arrowtypes": "", "arrowtypes": "",
"arrowtype_sharp": "", "arrowtype_sharp": "",
"arrowtype_round": "", "arrowtype_round": "",
@@ -182,11 +171,7 @@
"linkToElement": "", "linkToElement": "",
"wrapSelectionInFrame": "", "wrapSelectionInFrame": "",
"tab": "", "tab": "",
"shapeSwitch": "", "shapeSwitch": ""
"preferences": "",
"preferences_toolLock": "",
"arrowBinding": "",
"midpointSnapping": ""
}, },
"elementLink": { "elementLink": {
"title": "", "title": "",
@@ -410,10 +395,6 @@
"errorDialog": { "errorDialog": {
"title": "ਗਲਤੀ" "title": "ਗਲਤੀ"
}, },
"progressDialog": {
"title": "",
"defaultMessage": ""
},
"exportDialog": { "exportDialog": {
"disk_title": "ਡਿਸਕ ਵਿੱਚ ਸਾਂਭੋ", "disk_title": "ਡਿਸਕ ਵਿੱਚ ਸਾਂਭੋ",
"disk_details": "ਦ੍ਰਿਸ਼ ਦਾ ਡਾਟਾ ਫਾਈਲ ਵਿੱਚ ਨਿਰਯਾਤ ਕਰੋ ਜਿੱਥੋਂ ਤੁਸੀਂ ਇਸਨੂੰ ਬਾਅਦ ਵਿੱਚ ਆਯਾਤ ਕਰ ਸਕਦੇ ਹੋ।", "disk_details": "ਦ੍ਰਿਸ਼ ਦਾ ਡਾਟਾ ਫਾਈਲ ਵਿੱਚ ਨਿਰਯਾਤ ਕਰੋ ਜਿੱਥੋਂ ਤੁਸੀਂ ਇਸਨੂੰ ਬਾਅਦ ਵਿੱਚ ਆਯਾਤ ਕਰ ਸਕਦੇ ਹੋ।",
@@ -635,8 +616,7 @@
"syntax": "", "syntax": "",
"preview": "", "preview": "",
"label": "", "label": "",
"inputPlaceholder": "", "inputPlaceholder": ""
"autoFixAvailable": ""
}, },
"ttd": { "ttd": {
"error": "" "error": ""
+52 -52
View File
@@ -1,59 +1,59 @@
{ {
"ar-SA": 82, "ar-SA": 84,
"az-AZ": 24, "az-AZ": 25,
"bg-BG": 63, "bg-BG": 65,
"bn-BD": 38, "bn-BD": 39,
"bn-IN": 38, "bn-IN": 39,
"ca-ES": 82, "ca-ES": 84,
"cs-CZ": 74, "cs-CZ": 76,
"da-DK": 28, "da-DK": 28,
"de-CH": 83, "de-CH": 85,
"de-DE": 83, "de-DE": 85,
"el-GR": 77, "el-GR": 80,
"en": 100, "en": 100,
"es-ES": 82, "es-ES": 85,
"eu-ES": 70, "eu-ES": 72,
"fa-IR": 83, "fa-IR": 84,
"fi-FI": 60, "fi-FI": 62,
"fr-FR": 97, "fr-FR": 92,
"gl-ES": 61, "gl-ES": 63,
"he-IL": 82, "he-IL": 84,
"hi-IN": 83, "hi-IN": 86,
"hu-HU": 65, "hu-HU": 67,
"id-ID": 81, "id-ID": 84,
"it-IT": 98, "it-IT": 99,
"ja-JP": 96, "ja-JP": 81,
"kaa": 21, "kaa": 22,
"kab-KAB": 54, "kab-KAB": 56,
"kk-KZ": 13, "kk-KZ": 13,
"km-KH": 54, "km-KH": 56,
"ko-KR": 73, "ko-KR": 75,
"ku-TR": 58, "ku-TR": 59,
"lt-LT": 33, "lt-LT": 35,
"lv-LV": 51, "lv-LV": 53,
"mr-IN": 82, "mr-IN": 84,
"my-MM": 24, "my-MM": 25,
"nb-NO": 82, "nb-NO": 84,
"nl-NL": 96, "nl-NL": 99,
"nn-NO": 43, "nn-NO": 45,
"oc-FR": 76, "oc-FR": 79,
"pa-IN": 52, "pa-IN": 54,
"pl-PL": 90, "pl-PL": 93,
"pt-BR": 86, "pt-BR": 84,
"pt-PT": 82, "pt-PT": 84,
"ro-RO": 98, "ro-RO": 100,
"ru-RU": 98, "ru-RU": 99,
"si-LK": 67, "si-LK": 70,
"sk-SK": 90, "sk-SK": 93,
"sl-SI": 82, "sl-SI": 84,
"sv-SE": 82, "sv-SE": 85,
"ta-IN": 78, "ta-IN": 81,
"th-TH": 65, "th-TH": 59,
"tr-TR": 92, "tr-TR": 88,
"uk-UA": 86, "uk-UA": 84,
"uz-UZ": 0, "uz-UZ": 0,
"vi-VN": 68, "vi-VN": 70,
"zh-CN": 91, "zh-CN": 93,
"zh-HK": 16, "zh-HK": 16,
"zh-TW": 98 "zh-TW": 84
} }
+3 -23
View File
@@ -3,10 +3,6 @@
"paste": "Wklej", "paste": "Wklej",
"pasteAsPlaintext": "Wklej jako zwykły tekst", "pasteAsPlaintext": "Wklej jako zwykły tekst",
"pasteCharts": "Wklej wykresy", "pasteCharts": "Wklej wykresy",
"chartType_bar": "",
"chartType_line": "",
"chartType_radar": "",
"chartType_plaintext": "",
"selectAll": "Zaznacz wszystko", "selectAll": "Zaznacz wszystko",
"multiSelect": "Dodaj element do zaznaczenia", "multiSelect": "Dodaj element do zaznaczenia",
"moveCanvas": "Przesuń obszar roboczy", "moveCanvas": "Przesuń obszar roboczy",
@@ -53,14 +49,7 @@
"arrowhead_crowfoot_many": "Notacja Martina (wiele)", "arrowhead_crowfoot_many": "Notacja Martina (wiele)",
"arrowhead_crowfoot_one": "Notacja Martina (jeden)", "arrowhead_crowfoot_one": "Notacja Martina (jeden)",
"arrowhead_crowfoot_one_or_many": "Notacja Martina (jeden lub wiele)", "arrowhead_crowfoot_one_or_many": "Notacja Martina (jeden lub wiele)",
"arrowhead_cardinality_one": "",
"arrowhead_cardinality_many": "",
"arrowhead_cardinality_one_or_many": "",
"arrowhead_cardinality_exactly_one": "",
"arrowhead_cardinality_zero_or_one": "",
"arrowhead_cardinality_zero_or_many": "",
"more_options": "Więcej opcji", "more_options": "Więcej opcji",
"cardinality": "",
"arrowtypes": "Typ strzałki", "arrowtypes": "Typ strzałki",
"arrowtype_sharp": "Ostra strzałka", "arrowtype_sharp": "Ostra strzałka",
"arrowtype_round": "Zaokrąglona strzałka", "arrowtype_round": "Zaokrąglona strzałka",
@@ -182,11 +171,7 @@
"linkToElement": "Link do obiektu", "linkToElement": "Link do obiektu",
"wrapSelectionInFrame": "Owiń wybór w ramkę", "wrapSelectionInFrame": "Owiń wybór w ramkę",
"tab": "Tab", "tab": "Tab",
"shapeSwitch": "Wybór kształtu", "shapeSwitch": "Wybór kształtu"
"preferences": "",
"preferences_toolLock": "",
"arrowBinding": "",
"midpointSnapping": ""
}, },
"elementLink": { "elementLink": {
"title": "Link do obiektu", "title": "Link do obiektu",
@@ -410,10 +395,6 @@
"errorDialog": { "errorDialog": {
"title": "Wystąpił błąd" "title": "Wystąpił błąd"
}, },
"progressDialog": {
"title": "",
"defaultMessage": ""
},
"exportDialog": { "exportDialog": {
"disk_title": "Zapisz na dysku", "disk_title": "Zapisz na dysku",
"disk_details": "Eksportuj dane sceny do pliku, z którego możesz importować później.", "disk_details": "Eksportuj dane sceny do pliku, z którego możesz importować później.",
@@ -631,12 +612,11 @@
"mermaid": { "mermaid": {
"title": "Konwertuj diagram Mermaid do Excalidraw", "title": "Konwertuj diagram Mermaid do Excalidraw",
"button": "Wstaw", "button": "Wstaw",
"description": "", "description": "Obecnie wspierane są jedynie <flowchartLink>proste grafy</flowchartLink>, <sequenceLink>sekwencje</sequenceLink> i <classLink>diagramy klas</classLink>. Pozostałe typy będą wyświetlane jako obrazy w Excalidraw.",
"syntax": "Składnia diagramów Mermaid", "syntax": "Składnia diagramów Mermaid",
"preview": "Podgląd", "preview": "Podgląd",
"label": "", "label": "",
"inputPlaceholder": "", "inputPlaceholder": ""
"autoFixAvailable": ""
}, },
"ttd": { "ttd": {
"error": "" "error": ""
+26 -46
View File
@@ -3,10 +3,6 @@
"paste": "Colar", "paste": "Colar",
"pasteAsPlaintext": "Colar como texto sem formatação", "pasteAsPlaintext": "Colar como texto sem formatação",
"pasteCharts": "Colar gráficos", "pasteCharts": "Colar gráficos",
"chartType_bar": "",
"chartType_line": "",
"chartType_radar": "",
"chartType_plaintext": "",
"selectAll": "Selecionar tudo", "selectAll": "Selecionar tudo",
"multiSelect": "Adicionar elemento à seleção", "multiSelect": "Adicionar elemento à seleção",
"moveCanvas": "Mover tela", "moveCanvas": "Mover tela",
@@ -53,14 +49,7 @@
"arrowhead_crowfoot_many": "Pé de pássaro (muitos)", "arrowhead_crowfoot_many": "Pé de pássaro (muitos)",
"arrowhead_crowfoot_one": "Pé de pássaro (um)", "arrowhead_crowfoot_one": "Pé de pássaro (um)",
"arrowhead_crowfoot_one_or_many": "Pé de pássaro (um ou muitos)", "arrowhead_crowfoot_one_or_many": "Pé de pássaro (um ou muitos)",
"arrowhead_cardinality_one": "",
"arrowhead_cardinality_many": "",
"arrowhead_cardinality_one_or_many": "",
"arrowhead_cardinality_exactly_one": "",
"arrowhead_cardinality_zero_or_one": "",
"arrowhead_cardinality_zero_or_many": "",
"more_options": "Mais opções", "more_options": "Mais opções",
"cardinality": "",
"arrowtypes": "Tipo de seta", "arrowtypes": "Tipo de seta",
"arrowtype_sharp": "Seta afiada", "arrowtype_sharp": "Seta afiada",
"arrowtype_round": "Seta curva", "arrowtype_round": "Seta curva",
@@ -146,15 +135,15 @@
"labelEmbed": "Vincular e incorporar", "labelEmbed": "Vincular e incorporar",
"empty": "Nenhum link foi definido", "empty": "Nenhum link foi definido",
"hint": "Digite ou cole o seu link aqui", "hint": "Digite ou cole o seu link aqui",
"goToElement": "Ir para o elemento alvo" "goToElement": ""
}, },
"lineEditor": { "lineEditor": {
"edit": "Editar linha", "edit": "Editar linha",
"editArrow": "Editar seta" "editArrow": "Editar seta"
}, },
"polygon": { "polygon": {
"breakPolygon": "Parar polígono", "breakPolygon": "",
"convertToPolygon": "Converter para polígono" "convertToPolygon": ""
}, },
"elementLock": { "elementLock": {
"lock": "Bloquear", "lock": "Bloquear",
@@ -181,15 +170,11 @@
"copyElementLink": "Copiar link para o objeto", "copyElementLink": "Copiar link para o objeto",
"linkToElement": "Links para o objeto", "linkToElement": "Links para o objeto",
"wrapSelectionInFrame": "Ajustar seleção no frame", "wrapSelectionInFrame": "Ajustar seleção no frame",
"tab": "Aba", "tab": "",
"shapeSwitch": "Trocar forma", "shapeSwitch": ""
"preferences": "Preferências",
"preferences_toolLock": "Bloqueio de ferramenta",
"arrowBinding": "",
"midpointSnapping": ""
}, },
"elementLink": { "elementLink": {
"title": "Links para o objeto", "title": "",
"desc": "Clique em uma forma na tela ou cole um link.", "desc": "Clique em uma forma na tela ou cole um link.",
"notFound": "Objeto vinculado não foi encontrado na tela." "notFound": "Objeto vinculado não foi encontrado na tela."
}, },
@@ -199,9 +184,9 @@
"hint_emptyPrivateLibrary": "Selecione um item na tela para adicioná-lo aqui.", "hint_emptyPrivateLibrary": "Selecione um item na tela para adicioná-lo aqui.",
"search": { "search": {
"inputPlaceholder": "", "inputPlaceholder": "",
"heading": "Correspondências da biblioteca", "heading": "",
"noResults": "Nenhum resultado encontrado...", "noResults": "",
"clearSearch": "Limpar pesquisa" "clearSearch": ""
} }
}, },
"search": { "search": {
@@ -210,8 +195,8 @@
"singleResult": "resultado", "singleResult": "resultado",
"multipleResults": "resultados", "multipleResults": "resultados",
"placeholder": "Procurar texto na tela...", "placeholder": "Procurar texto na tela...",
"frames": "Quadros", "frames": "",
"texts": "Textos" "texts": ""
}, },
"buttons": { "buttons": {
"clearReset": "Limpar a tela", "clearReset": "Limpar a tela",
@@ -245,7 +230,7 @@
"objectsSnapMode": "Encaixar em objetos", "objectsSnapMode": "Encaixar em objetos",
"exitZenMode": "Sair do modo zen", "exitZenMode": "Sair do modo zen",
"cancel": "Cancelar", "cancel": "Cancelar",
"saveLibNames": "Salvar nome(s) e sair", "saveLibNames": "",
"clear": "Limpar", "clear": "Limpar",
"remove": "Remover", "remove": "Remover",
"embed": "Alternar incorporação", "embed": "Alternar incorporação",
@@ -276,7 +261,7 @@
"removeItemsFromsLibrary": "Excluir {{count}} item(ns) da biblioteca?", "removeItemsFromsLibrary": "Excluir {{count}} item(ns) da biblioteca?",
"invalidEncryptionKey": "A chave de encriptação deve ter 22 caracteres. A colaboração ao vivo está desabilitada.", "invalidEncryptionKey": "A chave de encriptação deve ter 22 caracteres. A colaboração ao vivo está desabilitada.",
"collabOfflineWarning": "Sem conexão com a internet disponível.\nSuas alterações não serão salvas!", "collabOfflineWarning": "Sem conexão com a internet disponível.\nSuas alterações não serão salvas!",
"localStorageQuotaExceeded": "A cota de armazenamento do navegador excedida. As alterações não serão salvas." "localStorageQuotaExceeded": ""
}, },
"errors": { "errors": {
"unsupportedFileType": "Tipo de arquivo não suportado.", "unsupportedFileType": "Tipo de arquivo não suportado.",
@@ -328,7 +313,7 @@
"hand": "Mão (ferramenta de rolagem)", "hand": "Mão (ferramenta de rolagem)",
"extraTools": "Mais ferramentas", "extraTools": "Mais ferramentas",
"mermaidToExcalidraw": "Mermaid para Excalidraw", "mermaidToExcalidraw": "Mermaid para Excalidraw",
"convertElementType": "Alternar tipo de forma" "convertElementType": ""
}, },
"element": { "element": {
"rectangle": "Retângulo", "rectangle": "Retângulo",
@@ -352,7 +337,7 @@
"shapes": "Formas" "shapes": "Formas"
}, },
"hints": { "hints": {
"dismissSearch": "{{shortcut}} para descartar a pesquisa", "dismissSearch": "",
"canvasPanning": "", "canvasPanning": "",
"linearElement": "Clique para iniciar vários pontos, arraste para uma única linha", "linearElement": "Clique para iniciar vários pontos, arraste para uma única linha",
"arrowTool": "", "arrowTool": "",
@@ -372,8 +357,8 @@
"lineEditor_pointSelected": "", "lineEditor_pointSelected": "",
"lineEditor_nothingSelected": "", "lineEditor_nothingSelected": "",
"publishLibrary": "Publicar sua própria biblioteca", "publishLibrary": "Publicar sua própria biblioteca",
"bindTextToElement": "{{shortcut}} para adicionar texto", "bindTextToElement": "",
"createFlowchart": "{{shortcut}} para criar um fluxo", "createFlowchart": "",
"deepBoxSelect": "", "deepBoxSelect": "",
"eraserRevert": "", "eraserRevert": "",
"firefox_clipboard_write": "Esse recurso pode ser ativado configurando a opção \"dom.events.asyncClipboard.clipboardItem\" como \"true\". Para alterar os sinalizadores do navegador no Firefox, visite a página \"about:config\".", "firefox_clipboard_write": "Esse recurso pode ser ativado configurando a opção \"dom.events.asyncClipboard.clipboardItem\" como \"true\". Para alterar os sinalizadores do navegador no Firefox, visite a página \"about:config\".",
@@ -410,10 +395,6 @@
"errorDialog": { "errorDialog": {
"title": "Erro" "title": "Erro"
}, },
"progressDialog": {
"title": "",
"defaultMessage": ""
},
"exportDialog": { "exportDialog": {
"disk_title": "Salvar no computador", "disk_title": "Salvar no computador",
"disk_details": "Exportar os dados da cena para um arquivo que você poderá importar mais tarde.", "disk_details": "Exportar os dados da cena para um arquivo que você poderá importar mais tarde.",
@@ -555,7 +536,7 @@
"pasteAsSingleElement": "Use {{shortcut}} para colar como um único elemento,\nou cole em um editor de texto já existente", "pasteAsSingleElement": "Use {{shortcut}} para colar como um único elemento,\nou cole em um editor de texto já existente",
"unableToEmbed": "No momento não é permitido incorporar esta URL. Crie uma issue no GitHub para solicitar a lista branca da URL", "unableToEmbed": "No momento não é permitido incorporar esta URL. Crie uma issue no GitHub para solicitar a lista branca da URL",
"unrecognizedLinkFormat": "O link incorporado não corresponde ao formato esperado. Por favor, tente colar a string 'incorporada' que foi fornecida pelo site de origem", "unrecognizedLinkFormat": "O link incorporado não corresponde ao formato esperado. Por favor, tente colar a string 'incorporada' que foi fornecida pelo site de origem",
"elementLinkCopied": "Link copiado para a área de transferência" "elementLinkCopied": ""
}, },
"colors": { "colors": {
"transparent": "Transparente", "transparent": "Transparente",
@@ -576,8 +557,8 @@
}, },
"welcomeScreen": { "welcomeScreen": {
"app": { "app": {
"center_heading": "Seus desenhos estão salvos no armazenamento do seu navegador.", "center_heading": "",
"center_heading_line2": "O armazenamento do navegador pode ser apagado inesperadamente.", "center_heading_line2": "",
"center_heading_line3": "", "center_heading_line3": "",
"center_heading_plus": "Você queria ir para o Excalidraw+ em vez disso?", "center_heading_plus": "Você queria ir para o Excalidraw+ em vez disso?",
"menuHint": "Exportar, preferências, idiomas..." "menuHint": "Exportar, preferências, idiomas..."
@@ -590,7 +571,7 @@
} }
}, },
"colorPicker": { "colorPicker": {
"color": "Cor", "color": "",
"mostUsedCustomColors": "Cores personalizadas mais usadas", "mostUsedCustomColors": "Cores personalizadas mais usadas",
"colors": "Cores", "colors": "Cores",
"shades": "Tons", "shades": "Tons",
@@ -631,19 +612,18 @@
"mermaid": { "mermaid": {
"title": "Mermaid para Excalidraw", "title": "Mermaid para Excalidraw",
"button": "Inserir", "button": "Inserir",
"description": "", "description": "Atualmente apenas os diagramas<flowchartLink>Flowchart</flowchartLink><sequenceLink>Sequência,</sequenceLink> e <classLink>Class</classLink>são suportados. Os outros tipos serão renderizados como uma imagem no Excalidraw.",
"syntax": "Sintaxe em Mermaid", "syntax": "Sintaxe em Mermaid",
"preview": "Visualizar", "preview": "Visualizar",
"label": "Mermaid", "label": "",
"inputPlaceholder": "Escreva definição de diagrama Mermaid aqui...", "inputPlaceholder": ""
"autoFixAvailable": ""
}, },
"ttd": { "ttd": {
"error": "Erro!" "error": ""
}, },
"chat": { "chat": {
"inputPlaceholder": "", "inputPlaceholder": "",
"inputPlaceholderWithMessages": "Continuar refinando seu diagrama...", "inputPlaceholderWithMessages": "",
"generating": "", "generating": "",
"rateLimitRemaining": "", "rateLimitRemaining": "",
"role": { "role": {
+3 -23
View File
@@ -3,10 +3,6 @@
"paste": "Colar", "paste": "Colar",
"pasteAsPlaintext": "Colar como texto simples", "pasteAsPlaintext": "Colar como texto simples",
"pasteCharts": "Colar gráficos", "pasteCharts": "Colar gráficos",
"chartType_bar": "",
"chartType_line": "",
"chartType_radar": "",
"chartType_plaintext": "",
"selectAll": "Selecionar tudo", "selectAll": "Selecionar tudo",
"multiSelect": "Adicionar elemento à seleção", "multiSelect": "Adicionar elemento à seleção",
"moveCanvas": "Mover área de desenho", "moveCanvas": "Mover área de desenho",
@@ -53,14 +49,7 @@
"arrowhead_crowfoot_many": "Pé de coroa (muitos)", "arrowhead_crowfoot_many": "Pé de coroa (muitos)",
"arrowhead_crowfoot_one": "Pé de coroa (um)", "arrowhead_crowfoot_one": "Pé de coroa (um)",
"arrowhead_crowfoot_one_or_many": "Pé de coroa (um ou muitos)", "arrowhead_crowfoot_one_or_many": "Pé de coroa (um ou muitos)",
"arrowhead_cardinality_one": "",
"arrowhead_cardinality_many": "",
"arrowhead_cardinality_one_or_many": "",
"arrowhead_cardinality_exactly_one": "",
"arrowhead_cardinality_zero_or_one": "",
"arrowhead_cardinality_zero_or_many": "",
"more_options": "Mais opções", "more_options": "Mais opções",
"cardinality": "",
"arrowtypes": "Tipo de seta", "arrowtypes": "Tipo de seta",
"arrowtype_sharp": "Seta retilínea", "arrowtype_sharp": "Seta retilínea",
"arrowtype_round": "Seta curva", "arrowtype_round": "Seta curva",
@@ -182,11 +171,7 @@
"linkToElement": "Hiperligação para o objeto", "linkToElement": "Hiperligação para o objeto",
"wrapSelectionInFrame": "Ajustar seleção no quadro", "wrapSelectionInFrame": "Ajustar seleção no quadro",
"tab": "", "tab": "",
"shapeSwitch": "", "shapeSwitch": ""
"preferences": "",
"preferences_toolLock": "",
"arrowBinding": "",
"midpointSnapping": ""
}, },
"elementLink": { "elementLink": {
"title": "Hiperligação para o objeto", "title": "Hiperligação para o objeto",
@@ -410,10 +395,6 @@
"errorDialog": { "errorDialog": {
"title": "Erro" "title": "Erro"
}, },
"progressDialog": {
"title": "",
"defaultMessage": ""
},
"exportDialog": { "exportDialog": {
"disk_title": "Guardar no disco", "disk_title": "Guardar no disco",
"disk_details": "Exportar os dados da cena para um ficheiro do qual poderá importar mais tarde.", "disk_details": "Exportar os dados da cena para um ficheiro do qual poderá importar mais tarde.",
@@ -631,12 +612,11 @@
"mermaid": { "mermaid": {
"title": "Mermaid para Excalidraw", "title": "Mermaid para Excalidraw",
"button": "Inserir", "button": "Inserir",
"description": "", "description": "Atualmente apenas são suportados diagramas <flowchartLink>fluxo</flowchartLink>, <sequenceLink>sequência, </sequenceLink> e <classLink>classe</classLink>. Os outros tipos serão renderizados como imagem no Excalidraw.",
"syntax": "Sintaxe Mermaid", "syntax": "Sintaxe Mermaid",
"preview": "Pré-visualizar", "preview": "Pré-visualizar",
"label": "", "label": "",
"inputPlaceholder": "", "inputPlaceholder": ""
"autoFixAvailable": ""
}, },
"ttd": { "ttd": {
"error": "" "error": ""
+4 -24
View File
@@ -3,10 +3,6 @@
"paste": "Lipire", "paste": "Lipire",
"pasteAsPlaintext": "Inserare ca text simplu", "pasteAsPlaintext": "Inserare ca text simplu",
"pasteCharts": "Lipire diagrame", "pasteCharts": "Lipire diagrame",
"chartType_bar": "Diagramă cu bare",
"chartType_line": "Diagramă cu linii",
"chartType_radar": "Diagramă radar",
"chartType_plaintext": "Text simplu",
"selectAll": "Selectare totală", "selectAll": "Selectare totală",
"multiSelect": "Adaugă element la selecție", "multiSelect": "Adaugă element la selecție",
"moveCanvas": "Mutare pânză", "moveCanvas": "Mutare pânză",
@@ -53,14 +49,7 @@
"arrowhead_crowfoot_many": "Model entitate-asociere (multe)", "arrowhead_crowfoot_many": "Model entitate-asociere (multe)",
"arrowhead_crowfoot_one": "Model entitate-asociere (unul)", "arrowhead_crowfoot_one": "Model entitate-asociere (unul)",
"arrowhead_crowfoot_one_or_many": "Model entitate-asociere (unul sau multe)", "arrowhead_crowfoot_one_or_many": "Model entitate-asociere (unul sau multe)",
"arrowhead_cardinality_one": "",
"arrowhead_cardinality_many": "",
"arrowhead_cardinality_one_or_many": "",
"arrowhead_cardinality_exactly_one": "",
"arrowhead_cardinality_zero_or_one": "",
"arrowhead_cardinality_zero_or_many": "",
"more_options": "Mai multe opțiuni", "more_options": "Mai multe opțiuni",
"cardinality": "",
"arrowtypes": "Tip de săgeată", "arrowtypes": "Tip de săgeată",
"arrowtype_sharp": "Săgeată ascuțită", "arrowtype_sharp": "Săgeată ascuțită",
"arrowtype_round": "Săgeată curbată", "arrowtype_round": "Săgeată curbată",
@@ -182,11 +171,7 @@
"linkToElement": "Link către obiect", "linkToElement": "Link către obiect",
"wrapSelectionInFrame": "Încapsulare selecție în cadru", "wrapSelectionInFrame": "Încapsulare selecție în cadru",
"tab": "Filă", "tab": "Filă",
"shapeSwitch": "Comutare formă", "shapeSwitch": "Comutare formă"
"preferences": "Preferințe",
"preferences_toolLock": "Blocare instrument",
"arrowBinding": "Legare săgeată",
"midpointSnapping": "Ancorare la punctele medii"
}, },
"elementLink": { "elementLink": {
"title": "Link către obiect", "title": "Link către obiect",
@@ -410,10 +395,6 @@
"errorDialog": { "errorDialog": {
"title": "Eroare" "title": "Eroare"
}, },
"progressDialog": {
"title": "În curs de salvare",
"defaultMessage": "Se pregătește salvarea..."
},
"exportDialog": { "exportDialog": {
"disk_title": "Salvare pe disc", "disk_title": "Salvare pe disc",
"disk_details": "Exportă datele scenei pe un fișier din care poți importa mai târziu.", "disk_details": "Exportă datele scenei pe un fișier din care poți importa mai târziu.",
@@ -631,12 +612,11 @@
"mermaid": { "mermaid": {
"title": "Mermaid la Excalidraw", "title": "Mermaid la Excalidraw",
"button": "Introducere", "button": "Introducere",
"description": "", "description": "În prezent, numai <flowchartLink>Organigramele</flowchartLink>, <sequenceLink>Diagramele de secvență</sequenceLink> și <classLink>Diagramele de clasă</classLink> sunt acceptate. Celelalte tipuri vor fi redate ca imagine în Excalidraw.",
"syntax": "Sintaxă Mermaid", "syntax": "Sintaxă Mermaid",
"preview": "Previzualizare", "preview": "Previzualizare",
"label": "Mermaid", "label": "Mermaid",
"inputPlaceholder": "Scrie definiţia diagramei Mermaid aici...", "inputPlaceholder": "Scrie definiţia diagramei Mermaid aici..."
"autoFixAvailable": "Este disponibilă funcția de fixare automată"
}, },
"ttd": { "ttd": {
"error": "Eroare!" "error": "Eroare!"
@@ -661,7 +641,7 @@
"placeholder": { "placeholder": {
"title": "Hai să-ți proiectăm diagrama", "title": "Hai să-ți proiectăm diagrama",
"description": "Descrie diagrama pe care vrei să o creezi și o vom genera pentru tine.", "description": "Descrie diagrama pe care vrei să o creezi și o vom genera pentru tine.",
"hint": "" "hint": "În acest moment cunoaștem organigrame, diagrame de secvență și diagrame de clasă."
}, },
"preview": "Previzualizare", "preview": "Previzualizare",
"insert": "Introducere", "insert": "Introducere",
+9 -29
View File
@@ -3,10 +3,6 @@
"paste": "Вставить", "paste": "Вставить",
"pasteAsPlaintext": "Вставить как обычный текст", "pasteAsPlaintext": "Вставить как обычный текст",
"pasteCharts": "Вставить диаграммы", "pasteCharts": "Вставить диаграммы",
"chartType_bar": "Гистограмма",
"chartType_line": "Линейная диаграмма",
"chartType_radar": "Лепестковая диаграмма",
"chartType_plaintext": "Обычный текст",
"selectAll": "Выбрать всё", "selectAll": "Выбрать всё",
"multiSelect": "Добавить элемент в выделенный фрагмент", "multiSelect": "Добавить элемент в выделенный фрагмент",
"moveCanvas": "Переместить холст", "moveCanvas": "Переместить холст",
@@ -53,14 +49,7 @@
"arrowhead_crowfoot_many": "Морщинки (много)", "arrowhead_crowfoot_many": "Морщинки (много)",
"arrowhead_crowfoot_one": "Морщинки (одна)", "arrowhead_crowfoot_one": "Морщинки (одна)",
"arrowhead_crowfoot_one_or_many": "Морщинки (одна или много)", "arrowhead_crowfoot_one_or_many": "Морщинки (одна или много)",
"arrowhead_cardinality_one": "",
"arrowhead_cardinality_many": "",
"arrowhead_cardinality_one_or_many": "",
"arrowhead_cardinality_exactly_one": "",
"arrowhead_cardinality_zero_or_one": "",
"arrowhead_cardinality_zero_or_many": "",
"more_options": "Больше вариантов", "more_options": "Больше вариантов",
"cardinality": "",
"arrowtypes": "Тип стрелки", "arrowtypes": "Тип стрелки",
"arrowtype_sharp": "Острая стрелка", "arrowtype_sharp": "Острая стрелка",
"arrowtype_round": "Изогнутая стрелка", "arrowtype_round": "Изогнутая стрелка",
@@ -182,11 +171,7 @@
"linkToElement": "Ссылка на объект", "linkToElement": "Ссылка на объект",
"wrapSelectionInFrame": "Поместить выделенное в фрейм", "wrapSelectionInFrame": "Поместить выделенное в фрейм",
"tab": "Вкладка", "tab": "Вкладка",
"shapeSwitch": "Сменить форму", "shapeSwitch": "Сменить форму"
"preferences": "Настройки",
"preferences_toolLock": "Закрепить инструмент",
"arrowBinding": "Привязка стрелкой",
"midpointSnapping": "Привязка к средней точке"
}, },
"elementLink": { "elementLink": {
"title": "Ссылка на объект", "title": "Ссылка на объект",
@@ -410,10 +395,6 @@
"errorDialog": { "errorDialog": {
"title": "Ошибка" "title": "Ошибка"
}, },
"progressDialog": {
"title": "",
"defaultMessage": ""
},
"exportDialog": { "exportDialog": {
"disk_title": "Сохранить на диск", "disk_title": "Сохранить на диск",
"disk_details": "Экспортировать данные сцены в файл, из которого можно импортировать позже.", "disk_details": "Экспортировать данные сцены в файл, из которого можно импортировать позже.",
@@ -576,9 +557,9 @@
}, },
"welcomeScreen": { "welcomeScreen": {
"app": { "app": {
"center_heading": "Ваши рисунки сохраняются в памяти вашего браузера.", "center_heading": "",
"center_heading_line2": "Хранилище браузера может быть очищено неожиданно.", "center_heading_line2": "",
"center_heading_line3": "Сохраните свою работу в файл регулярно, чтобы избежать потери файла.", "center_heading_line3": "",
"center_heading_plus": "Хотите перейти на Excalidraw+?", "center_heading_plus": "Хотите перейти на Excalidraw+?",
"menuHint": "Экспорт, настройки, языки, ..." "menuHint": "Экспорт, настройки, языки, ..."
}, },
@@ -631,12 +612,11 @@
"mermaid": { "mermaid": {
"title": "Из Mermaid в Excalidraw", "title": "Из Mermaid в Excalidraw",
"button": "Вставить", "button": "Вставить",
"description": "", "description": "В настоящее время поддерживаются только <flowchartLink>блок-схемы</flowchartLink>, <sequenceLink>диаграммы последовательности</sequenceLink> и <classLink>диаграммы классов</classLink>. Другие типы будут отображаться в виде изображения в Excalidraw.",
"syntax": "Синтаксис Mermaid", "syntax": "Синтаксис Mermaid",
"preview": "Предпросмотр", "preview": "Предпросмотр",
"label": "Mermaid", "label": "Mermaid",
"inputPlaceholder": "Напишите здесь определение диаграммы Mermaid...", "inputPlaceholder": "Напишите здесь определение диаграммы Mermaid..."
"autoFixAvailable": "Автоисправление доступно"
}, },
"ttd": { "ttd": {
"error": "Ошибка!" "error": "Ошибка!"
@@ -644,7 +624,7 @@
"chat": { "chat": {
"inputPlaceholder": "Начните вводить сюда идею диаграммы... ({{shortcut}} для новой строки)", "inputPlaceholder": "Начните вводить сюда идею диаграммы... ({{shortcut}} для новой строки)",
"inputPlaceholderWithMessages": "Продолжайте доработку диаграммы...", "inputPlaceholderWithMessages": "Продолжайте доработку диаграммы...",
"generating": "Генерация...", "generating": "",
"rateLimitRemaining": "Осталось запросов сегодня: {{count}}", "rateLimitRemaining": "Осталось запросов сегодня: {{count}}",
"role": { "role": {
"user": "Вы", "user": "Вы",
@@ -661,7 +641,7 @@
"placeholder": { "placeholder": {
"title": "Давайте создадим вашу диаграмму", "title": "Давайте создадим вашу диаграмму",
"description": "Опишите диаграмму, которую вы хотите создать, и мы сгенерируем её для вас.", "description": "Опишите диаграмму, которую вы хотите создать, и мы сгенерируем её для вас.",
"hint": "" "hint": "На данный момент мы знаем диаграммы блок-схемы, последовательности и классов."
}, },
"preview": "Предпросмотр", "preview": "Предпросмотр",
"insert": "Вставить", "insert": "Вставить",
@@ -675,7 +655,7 @@
"aiRepair": "Перегенерировать (автоисправление) →", "aiRepair": "Перегенерировать (автоисправление) →",
"requestAborted": "Запрос отменён", "requestAborted": "Запрос отменён",
"requestFailed": "Запрос не удался", "requestFailed": "Запрос не удался",
"mermaidParseError": "Синтаксическая ошибка Mermaid" "mermaidParseError": ""
}, },
"rateLimit": { "rateLimit": {
"messageLimit": "Вы достигли лимита ИИ на бесплатном тарифном плане. Попробуйте Excalidraw+ или вернитесь завтра.", "messageLimit": "Вы достигли лимита ИИ на бесплатном тарифном плане. Попробуйте Excalidraw+ или вернитесь завтра.",
+3 -23
View File
@@ -3,10 +3,6 @@
"paste": "අලවන්න", "paste": "අලවන්න",
"pasteAsPlaintext": "සරල පෙළ ලෙස අලවන්න", "pasteAsPlaintext": "සරල පෙළ ලෙස අලවන්න",
"pasteCharts": "ප්‍රස්ථාරය", "pasteCharts": "ප්‍රස්ථාරය",
"chartType_bar": "",
"chartType_line": "",
"chartType_radar": "",
"chartType_plaintext": "",
"selectAll": "සියල්ලම", "selectAll": "සියල්ලම",
"multiSelect": "තෝරා ගැනීමට අංගය එකතු කරන්න", "multiSelect": "තෝරා ගැනීමට අංගය එකතු කරන්න",
"moveCanvas": "කැන්වසය චලනය කරන්න", "moveCanvas": "කැන්වසය චලනය කරන්න",
@@ -53,14 +49,7 @@
"arrowhead_crowfoot_many": "", "arrowhead_crowfoot_many": "",
"arrowhead_crowfoot_one": "", "arrowhead_crowfoot_one": "",
"arrowhead_crowfoot_one_or_many": "", "arrowhead_crowfoot_one_or_many": "",
"arrowhead_cardinality_one": "",
"arrowhead_cardinality_many": "",
"arrowhead_cardinality_one_or_many": "",
"arrowhead_cardinality_exactly_one": "",
"arrowhead_cardinality_zero_or_one": "",
"arrowhead_cardinality_zero_or_many": "",
"more_options": "", "more_options": "",
"cardinality": "",
"arrowtypes": "", "arrowtypes": "",
"arrowtype_sharp": "", "arrowtype_sharp": "",
"arrowtype_round": "", "arrowtype_round": "",
@@ -182,11 +171,7 @@
"linkToElement": "", "linkToElement": "",
"wrapSelectionInFrame": "", "wrapSelectionInFrame": "",
"tab": "", "tab": "",
"shapeSwitch": "", "shapeSwitch": ""
"preferences": "",
"preferences_toolLock": "",
"arrowBinding": "",
"midpointSnapping": ""
}, },
"elementLink": { "elementLink": {
"title": "", "title": "",
@@ -410,10 +395,6 @@
"errorDialog": { "errorDialog": {
"title": "දෝෂ සංවාද මාතෘකාව" "title": "දෝෂ සංවාද මාතෘකාව"
}, },
"progressDialog": {
"title": "",
"defaultMessage": ""
},
"exportDialog": { "exportDialog": {
"disk_title": "තැටි මාතෘකාව", "disk_title": "තැටි මාතෘකාව",
"disk_details": "තැටි විස්තර", "disk_details": "තැටි විස්තර",
@@ -631,12 +612,11 @@
"mermaid": { "mermaid": {
"title": "Mermaid මාතෘකාව", "title": "Mermaid මාතෘකාව",
"button": "Mermaid බොත්තම", "button": "Mermaid බොත්තම",
"description": "", "description": "Mermaid විස්තර",
"syntax": "Mermaid වාක්‍ය ඛණ්ඩය", "syntax": "Mermaid වාක්‍ය ඛණ්ඩය",
"preview": "Mermaid පූර්වදර්ශනය", "preview": "Mermaid පූර්වදර්ශනය",
"label": "", "label": "",
"inputPlaceholder": "", "inputPlaceholder": ""
"autoFixAvailable": ""
}, },
"ttd": { "ttd": {
"error": "" "error": ""
+3 -23
View File
@@ -3,10 +3,6 @@
"paste": "Vložiť", "paste": "Vložiť",
"pasteAsPlaintext": "Vložiť ako obyčajný text", "pasteAsPlaintext": "Vložiť ako obyčajný text",
"pasteCharts": "Vložiť grafy", "pasteCharts": "Vložiť grafy",
"chartType_bar": "",
"chartType_line": "",
"chartType_radar": "",
"chartType_plaintext": "",
"selectAll": "Vybrať všetko", "selectAll": "Vybrať všetko",
"multiSelect": "Pridať prvok do výberu", "multiSelect": "Pridať prvok do výberu",
"moveCanvas": "Pohyb plátna", "moveCanvas": "Pohyb plátna",
@@ -53,14 +49,7 @@
"arrowhead_crowfoot_many": "Crow's foot (viacero)", "arrowhead_crowfoot_many": "Crow's foot (viacero)",
"arrowhead_crowfoot_one": "Crow's foot (jedna)", "arrowhead_crowfoot_one": "Crow's foot (jedna)",
"arrowhead_crowfoot_one_or_many": "Crow's foot (jedna k viacero)", "arrowhead_crowfoot_one_or_many": "Crow's foot (jedna k viacero)",
"arrowhead_cardinality_one": "",
"arrowhead_cardinality_many": "",
"arrowhead_cardinality_one_or_many": "",
"arrowhead_cardinality_exactly_one": "",
"arrowhead_cardinality_zero_or_one": "",
"arrowhead_cardinality_zero_or_many": "",
"more_options": "Ďalšie možnosti", "more_options": "Ďalšie možnosti",
"cardinality": "",
"arrowtypes": "Typ šípky", "arrowtypes": "Typ šípky",
"arrowtype_sharp": "Ostrá šípka", "arrowtype_sharp": "Ostrá šípka",
"arrowtype_round": "Zakrivená šípka", "arrowtype_round": "Zakrivená šípka",
@@ -182,11 +171,7 @@
"linkToElement": "Odkaz na objekt", "linkToElement": "Odkaz na objekt",
"wrapSelectionInFrame": "Zabaliť výber do rámu", "wrapSelectionInFrame": "Zabaliť výber do rámu",
"tab": "Tab", "tab": "Tab",
"shapeSwitch": "Zmeniť tvar", "shapeSwitch": "Zmeniť tvar"
"preferences": "",
"preferences_toolLock": "",
"arrowBinding": "",
"midpointSnapping": ""
}, },
"elementLink": { "elementLink": {
"title": "Odkaz na objekt", "title": "Odkaz na objekt",
@@ -410,10 +395,6 @@
"errorDialog": { "errorDialog": {
"title": "Chyba" "title": "Chyba"
}, },
"progressDialog": {
"title": "",
"defaultMessage": ""
},
"exportDialog": { "exportDialog": {
"disk_title": "Uložiť na disk", "disk_title": "Uložiť na disk",
"disk_details": "Exportovať údaje scény do súboru, z ktorého môžu byť neskôr importované.", "disk_details": "Exportovať údaje scény do súboru, z ktorého môžu byť neskôr importované.",
@@ -631,12 +612,11 @@
"mermaid": { "mermaid": {
"title": "Mermaid do Excalidraw", "title": "Mermaid do Excalidraw",
"button": "Vložiť", "button": "Vložiť",
"description": "", "description": "Aktuálne sú podporované iba <flowchartLink>vývojové diagramy</flowchartLink>, <sequenceLink>sekvenčné diagramy</sequenceLink> a <classLink>diagramy tried</classLink>. Ostatné typy budú v Excalidraw vykreslené ako obrázky.",
"syntax": "Mermaid syntax", "syntax": "Mermaid syntax",
"preview": "Ukážka", "preview": "Ukážka",
"label": "", "label": "",
"inputPlaceholder": "", "inputPlaceholder": ""
"autoFixAvailable": ""
}, },
"ttd": { "ttd": {
"error": "" "error": ""
+3 -23
View File
@@ -3,10 +3,6 @@
"paste": "Prilepi", "paste": "Prilepi",
"pasteAsPlaintext": "Prilepi kot navadno besedilo", "pasteAsPlaintext": "Prilepi kot navadno besedilo",
"pasteCharts": "Prilepi grafikone", "pasteCharts": "Prilepi grafikone",
"chartType_bar": "",
"chartType_line": "",
"chartType_radar": "",
"chartType_plaintext": "",
"selectAll": "Izberi vse", "selectAll": "Izberi vse",
"multiSelect": "Dodaj element v izbor", "multiSelect": "Dodaj element v izbor",
"moveCanvas": "Premakni platno", "moveCanvas": "Premakni platno",
@@ -53,14 +49,7 @@
"arrowhead_crowfoot_many": "Vranja noga (več)", "arrowhead_crowfoot_many": "Vranja noga (več)",
"arrowhead_crowfoot_one": "Vranja noga (ena)", "arrowhead_crowfoot_one": "Vranja noga (ena)",
"arrowhead_crowfoot_one_or_many": "Vranja noga (ena ali več)", "arrowhead_crowfoot_one_or_many": "Vranja noga (ena ali več)",
"arrowhead_cardinality_one": "",
"arrowhead_cardinality_many": "",
"arrowhead_cardinality_one_or_many": "",
"arrowhead_cardinality_exactly_one": "",
"arrowhead_cardinality_zero_or_one": "",
"arrowhead_cardinality_zero_or_many": "",
"more_options": "Več možnosti", "more_options": "Več možnosti",
"cardinality": "",
"arrowtypes": "Vrsta puščice", "arrowtypes": "Vrsta puščice",
"arrowtype_sharp": "Ostra puščica", "arrowtype_sharp": "Ostra puščica",
"arrowtype_round": "Ukrivljena puščica", "arrowtype_round": "Ukrivljena puščica",
@@ -182,11 +171,7 @@
"linkToElement": "Povezava do objekta", "linkToElement": "Povezava do objekta",
"wrapSelectionInFrame": "Zavij izbor v okvir", "wrapSelectionInFrame": "Zavij izbor v okvir",
"tab": "", "tab": "",
"shapeSwitch": "", "shapeSwitch": ""
"preferences": "",
"preferences_toolLock": "",
"arrowBinding": "",
"midpointSnapping": ""
}, },
"elementLink": { "elementLink": {
"title": "Povezava do objekta", "title": "Povezava do objekta",
@@ -410,10 +395,6 @@
"errorDialog": { "errorDialog": {
"title": "Napaka" "title": "Napaka"
}, },
"progressDialog": {
"title": "",
"defaultMessage": ""
},
"exportDialog": { "exportDialog": {
"disk_title": "Shrani na disk", "disk_title": "Shrani na disk",
"disk_details": "Izvozite podatke scene v datoteko, iz katere jo lahko pozneje uvozite.", "disk_details": "Izvozite podatke scene v datoteko, iz katere jo lahko pozneje uvozite.",
@@ -631,12 +612,11 @@
"mermaid": { "mermaid": {
"title": "Mermaid v Excalidraw", "title": "Mermaid v Excalidraw",
"button": "Vstavi", "button": "Vstavi",
"description": "", "description": "Trenutno so podprti samo <flowchartLink>diagrami poteka</flowchartLink>, <sequenceLink>diagrami zaporedij</sequenceLink> in <classLink>Razredni diagrami</classLink>. Druge vrste bodo upodobljene kot slike v Excalidraw.",
"syntax": "Sintaksa Mermaid", "syntax": "Sintaksa Mermaid",
"preview": "Predogled", "preview": "Predogled",
"label": "", "label": "",
"inputPlaceholder": "", "inputPlaceholder": ""
"autoFixAvailable": ""
}, },
"ttd": { "ttd": {
"error": "" "error": ""
+3 -23
View File
@@ -3,10 +3,6 @@
"paste": "Klistra in", "paste": "Klistra in",
"pasteAsPlaintext": "Klistra som oformaterad text", "pasteAsPlaintext": "Klistra som oformaterad text",
"pasteCharts": "Klistra in diagram", "pasteCharts": "Klistra in diagram",
"chartType_bar": "",
"chartType_line": "",
"chartType_radar": "",
"chartType_plaintext": "",
"selectAll": "Markera alla", "selectAll": "Markera alla",
"multiSelect": "Lägg till element till markering", "multiSelect": "Lägg till element till markering",
"moveCanvas": "Flytta canvas", "moveCanvas": "Flytta canvas",
@@ -53,14 +49,7 @@
"arrowhead_crowfoot_many": "Kråkfot (många)", "arrowhead_crowfoot_many": "Kråkfot (många)",
"arrowhead_crowfoot_one": "Kråkfot (en)", "arrowhead_crowfoot_one": "Kråkfot (en)",
"arrowhead_crowfoot_one_or_many": "Kråkfot (en eller många)", "arrowhead_crowfoot_one_or_many": "Kråkfot (en eller många)",
"arrowhead_cardinality_one": "",
"arrowhead_cardinality_many": "",
"arrowhead_cardinality_one_or_many": "",
"arrowhead_cardinality_exactly_one": "",
"arrowhead_cardinality_zero_or_one": "",
"arrowhead_cardinality_zero_or_many": "",
"more_options": "Fler alternativ", "more_options": "Fler alternativ",
"cardinality": "",
"arrowtypes": "Piltyp", "arrowtypes": "Piltyp",
"arrowtype_sharp": "Rak", "arrowtype_sharp": "Rak",
"arrowtype_round": "Böjd", "arrowtype_round": "Böjd",
@@ -182,11 +171,7 @@
"linkToElement": "Länk till objektet", "linkToElement": "Länk till objektet",
"wrapSelectionInFrame": "Omslut urvaled i ram", "wrapSelectionInFrame": "Omslut urvaled i ram",
"tab": "Flik", "tab": "Flik",
"shapeSwitch": "", "shapeSwitch": ""
"preferences": "",
"preferences_toolLock": "",
"arrowBinding": "",
"midpointSnapping": ""
}, },
"elementLink": { "elementLink": {
"title": "Länk till objektet", "title": "Länk till objektet",
@@ -410,10 +395,6 @@
"errorDialog": { "errorDialog": {
"title": "Fel" "title": "Fel"
}, },
"progressDialog": {
"title": "",
"defaultMessage": ""
},
"exportDialog": { "exportDialog": {
"disk_title": "Spara till disk", "disk_title": "Spara till disk",
"disk_details": "Exportera skissdata till en fil som du kan importera från senare.", "disk_details": "Exportera skissdata till en fil som du kan importera från senare.",
@@ -631,12 +612,11 @@
"mermaid": { "mermaid": {
"title": "Mermaid till Excalidraw", "title": "Mermaid till Excalidraw",
"button": "Infoga", "button": "Infoga",
"description": "", "description": "För närvarande stöds endast <flowchartLink>Flödesdiagram</flowchartLink>,<sequenceLink> Sekvensdiagram </sequenceLink> och <classLink>Klassdiagram</classLink>. De andra typerna kommer att återges som bild i Excalidraw.",
"syntax": "Mermaid-syntax", "syntax": "Mermaid-syntax",
"preview": "Förhandsgranska", "preview": "Förhandsgranska",
"label": "", "label": "",
"inputPlaceholder": "", "inputPlaceholder": ""
"autoFixAvailable": ""
}, },
"ttd": { "ttd": {
"error": "" "error": ""
+2 -22
View File
@@ -3,10 +3,6 @@
"paste": "ஒட்டு", "paste": "ஒட்டு",
"pasteAsPlaintext": "அலங்காரமின்றி ஒட்டு", "pasteAsPlaintext": "அலங்காரமின்றி ஒட்டு",
"pasteCharts": "விளக்கப்படங்களை ஒட்டு", "pasteCharts": "விளக்கப்படங்களை ஒட்டு",
"chartType_bar": "",
"chartType_line": "",
"chartType_radar": "",
"chartType_plaintext": "",
"selectAll": "எல்லாம் தேர்ந்தெடு", "selectAll": "எல்லாம் தேர்ந்தெடு",
"multiSelect": "உறுப்பைத் தெரிவில் சேர்", "multiSelect": "உறுப்பைத் தெரிவில் சேர்",
"moveCanvas": "கித்தானை நகர்த்து", "moveCanvas": "கித்தானை நகர்த்து",
@@ -53,14 +49,7 @@
"arrowhead_crowfoot_many": "", "arrowhead_crowfoot_many": "",
"arrowhead_crowfoot_one": "", "arrowhead_crowfoot_one": "",
"arrowhead_crowfoot_one_or_many": "", "arrowhead_crowfoot_one_or_many": "",
"arrowhead_cardinality_one": "",
"arrowhead_cardinality_many": "",
"arrowhead_cardinality_one_or_many": "",
"arrowhead_cardinality_exactly_one": "",
"arrowhead_cardinality_zero_or_one": "",
"arrowhead_cardinality_zero_or_many": "",
"more_options": "கூடுதல் விருப்பங்கள்", "more_options": "கூடுதல் விருப்பங்கள்",
"cardinality": "",
"arrowtypes": "அம்புக்குறி வகை", "arrowtypes": "அம்புக்குறி வகை",
"arrowtype_sharp": "கூர்மையான குறி", "arrowtype_sharp": "கூர்மையான குறி",
"arrowtype_round": "வளைந்தக் குறி", "arrowtype_round": "வளைந்தக் குறி",
@@ -182,11 +171,7 @@
"linkToElement": "இணைப்பு", "linkToElement": "இணைப்பு",
"wrapSelectionInFrame": "தேர்வை வடிவத்தில் சுற்று", "wrapSelectionInFrame": "தேர்வை வடிவத்தில் சுற்று",
"tab": "", "tab": "",
"shapeSwitch": "", "shapeSwitch": ""
"preferences": "",
"preferences_toolLock": "",
"arrowBinding": "",
"midpointSnapping": ""
}, },
"elementLink": { "elementLink": {
"title": "இணைப்பு", "title": "இணைப்பு",
@@ -410,10 +395,6 @@
"errorDialog": { "errorDialog": {
"title": "பிழை" "title": "பிழை"
}, },
"progressDialog": {
"title": "",
"defaultMessage": ""
},
"exportDialog": { "exportDialog": {
"disk_title": "வட்டில் சேமி", "disk_title": "வட்டில் சேமி",
"disk_details": "காட்சித் தரவை நீங்கள் பின்னர் இறக்குமதி செய்யக்கூடிய ஒரு கோப்பிற்கு ஏற்றுமதிசெய்க.", "disk_details": "காட்சித் தரவை நீங்கள் பின்னர் இறக்குமதி செய்யக்கூடிய ஒரு கோப்பிற்கு ஏற்றுமதிசெய்க.",
@@ -635,8 +616,7 @@
"syntax": "மெர்மெய்டு தொடரியல்", "syntax": "மெர்மெய்டு தொடரியல்",
"preview": "முன்னோட்டம்", "preview": "முன்னோட்டம்",
"label": "", "label": "",
"inputPlaceholder": "", "inputPlaceholder": ""
"autoFixAvailable": ""
}, },
"ttd": { "ttd": {
"error": "" "error": ""
+47 -67
View File
@@ -3,10 +3,6 @@
"paste": "วาง", "paste": "วาง",
"pasteAsPlaintext": "วางโดยไม่มีการจัดรูปแบบ", "pasteAsPlaintext": "วางโดยไม่มีการจัดรูปแบบ",
"pasteCharts": "วางแผนภูมิ", "pasteCharts": "วางแผนภูมิ",
"chartType_bar": "",
"chartType_line": "แผนภูมิเส้น",
"chartType_radar": "",
"chartType_plaintext": "ข้อความธรรมดา",
"selectAll": "เลือกทั้งหมด", "selectAll": "เลือกทั้งหมด",
"multiSelect": "เพิ่มองค์ประกอบในการเลือก", "multiSelect": "เพิ่มองค์ประกอบในการเลือก",
"moveCanvas": "เคลื่อนย้ายผ้าใบ", "moveCanvas": "เคลื่อนย้ายผ้าใบ",
@@ -53,14 +49,7 @@
"arrowhead_crowfoot_many": "", "arrowhead_crowfoot_many": "",
"arrowhead_crowfoot_one": "", "arrowhead_crowfoot_one": "",
"arrowhead_crowfoot_one_or_many": "", "arrowhead_crowfoot_one_or_many": "",
"arrowhead_cardinality_one": "", "more_options": "",
"arrowhead_cardinality_many": "",
"arrowhead_cardinality_one_or_many": "",
"arrowhead_cardinality_exactly_one": "",
"arrowhead_cardinality_zero_or_one": "",
"arrowhead_cardinality_zero_or_many": "",
"more_options": "ตัวเลือกเพิ่มเติม",
"cardinality": "",
"arrowtypes": "ชนิดลูกศร", "arrowtypes": "ชนิดลูกศร",
"arrowtype_sharp": "ลูกศรแหลม", "arrowtype_sharp": "ลูกศรแหลม",
"arrowtype_round": "ลูกศรโค้ง", "arrowtype_round": "ลูกศรโค้ง",
@@ -181,12 +170,8 @@
"copyElementLink": "คัดลอกลิงค์ไปสู่วัตถุ", "copyElementLink": "คัดลอกลิงค์ไปสู่วัตถุ",
"linkToElement": "ลิงค์ไปสู่วัตถุ", "linkToElement": "ลิงค์ไปสู่วัตถุ",
"wrapSelectionInFrame": "", "wrapSelectionInFrame": "",
"tab": "แท็บ", "tab": "",
"shapeSwitch": "", "shapeSwitch": ""
"preferences": "การตั้งค่า",
"preferences_toolLock": "",
"arrowBinding": "",
"midpointSnapping": ""
}, },
"elementLink": { "elementLink": {
"title": "ลิงค์ไปสู่วัตถุ", "title": "ลิงค์ไปสู่วัตถุ",
@@ -198,20 +183,20 @@
"hint_emptyLibrary": "", "hint_emptyLibrary": "",
"hint_emptyPrivateLibrary": "", "hint_emptyPrivateLibrary": "",
"search": { "search": {
"inputPlaceholder": "ค้นหาห้องสมุด", "inputPlaceholder": "",
"heading": "", "heading": "",
"noResults": "", "noResults": "",
"clearSearch": "" "clearSearch": ""
} }
}, },
"search": { "search": {
"title": "ใช้บนผืนผ้าใบ", "title": "",
"noMatch": "ไม่พบรายการที่ตรงกัน...", "noMatch": "",
"singleResult": "ผลลัพธ์", "singleResult": "",
"multipleResults": "ผลลัพธ์", "multipleResults": "",
"placeholder": "ค้นหาข้อความในผืนผ้าใบ", "placeholder": "ค้นหาข้อความในผืนผ้าใบ",
"frames": "กรอบ", "frames": "",
"texts": "ข้อความ" "texts": ""
}, },
"buttons": { "buttons": {
"clearReset": "รีเซ็ทผืนผ้าใบ", "clearReset": "รีเซ็ทผืนผ้าใบ",
@@ -307,7 +292,7 @@
}, },
"toolBar": { "toolBar": {
"selection": "การเลือก", "selection": "การเลือก",
"lasso": "การเลือก Lasso", "lasso": "",
"image": "แทรกรูปภาพ", "image": "แทรกรูปภาพ",
"rectangle": "สี่เหลี่ยมผืนผ้า", "rectangle": "สี่เหลี่ยมผืนผ้า",
"diamond": "รูปเพชร", "diamond": "รูปเพชร",
@@ -408,14 +393,10 @@
"shareTitle": "" "shareTitle": ""
}, },
"errorDialog": { "errorDialog": {
"title": "ข้อผิดพลาด" "title": ""
},
"progressDialog": {
"title": "",
"defaultMessage": ""
}, },
"exportDialog": { "exportDialog": {
"disk_title": "บันทึกไปยังดิสก์", "disk_title": "",
"disk_details": "", "disk_details": "",
"disk_button": "บันทึกเป็นไฟล์", "disk_button": "บันทึกเป็นไฟล์",
"link_title": "ลิงก์ที่สามารถแชร์ได้", "link_title": "ลิงก์ที่สามารถแชร์ได้",
@@ -432,9 +413,9 @@
"deepBoxSelect": "", "deepBoxSelect": "",
"createFlowchart": "", "createFlowchart": "",
"navigateFlowchart": "", "navigateFlowchart": "",
"curvedArrow": "ลูกศรโค้ง", "curvedArrow": "",
"curvedLine": "เส้นโค้ง", "curvedLine": "",
"documentation": "เอกสารคู่มือ", "documentation": "",
"doubleClick": "ดับเบิลคลิก", "doubleClick": "ดับเบิลคลิก",
"drag": "ลาก", "drag": "ลาก",
"editor": "ตัวแก้ไข", "editor": "ตัวแก้ไข",
@@ -445,7 +426,7 @@
"or": "หรือ", "or": "หรือ",
"preventBinding": "", "preventBinding": "",
"tools": "เครื่องมือ", "tools": "เครื่องมือ",
"shortcuts": "แป้นพิมพ์ลัด", "shortcuts": "",
"textFinish": "", "textFinish": "",
"textNewLine": "", "textNewLine": "",
"title": "ช่วยเหลือ", "title": "ช่วยเหลือ",
@@ -459,15 +440,15 @@
"cropFinish": "" "cropFinish": ""
}, },
"clearCanvasDialog": { "clearCanvasDialog": {
"title": "ล้างผืนผ้าใบ" "title": ""
}, },
"publishDialog": { "publishDialog": {
"title": "", "title": "",
"itemName": "ชื่อสิ่งของ", "itemName": "",
"authorName": "ชื่อเจ้าของ", "authorName": "ชื่อเจ้าของ",
"githubUsername": "ชื่อผู้ใช้ GitHub", "githubUsername": "ชื่อผู้ใช้ GitHub",
"twitterUsername": "ชื่อผู้ใช้ Twitter", "twitterUsername": "ชื่อผู้ใช้ Twitter",
"libraryName": "ชื่อไลบรารี่", "libraryName": "",
"libraryDesc": "", "libraryDesc": "",
"website": "เว็บไซต์", "website": "เว็บไซต์",
"placeholder": { "placeholder": {
@@ -480,7 +461,7 @@
}, },
"errors": { "errors": {
"required": "จำเป็น", "required": "จำเป็น",
"website": "ป้อน URL ที่ถูกต้อง" "website": ""
}, },
"noteDescription": "", "noteDescription": "",
"noteGuidelines": "", "noteGuidelines": "",
@@ -494,7 +475,7 @@
"content": "" "content": ""
}, },
"confirmDialog": { "confirmDialog": {
"resetLibrary": "รีเซ็ตคลัง", "resetLibrary": "",
"removeItemsFromLib": "" "removeItemsFromLib": ""
}, },
"imageExportDialog": { "imageExportDialog": {
@@ -590,7 +571,7 @@
} }
}, },
"colorPicker": { "colorPicker": {
"color": "สี", "color": "",
"mostUsedCustomColors": "", "mostUsedCustomColors": "",
"colors": "สี", "colors": "สี",
"shades": "รูปร่าง", "shades": "รูปร่าง",
@@ -635,8 +616,7 @@
"syntax": "", "syntax": "",
"preview": "ดูตัวอย่าง", "preview": "ดูตัวอย่าง",
"label": "", "label": "",
"inputPlaceholder": "", "inputPlaceholder": ""
"autoFixAvailable": ""
}, },
"ttd": { "ttd": {
"error": "" "error": ""
@@ -644,32 +624,32 @@
"chat": { "chat": {
"inputPlaceholder": "", "inputPlaceholder": "",
"inputPlaceholderWithMessages": "", "inputPlaceholderWithMessages": "",
"generating": "กำลังสร้าง...", "generating": "",
"rateLimitRemaining": "", "rateLimitRemaining": "",
"role": { "role": {
"user": "คุณ", "user": "",
"assistant": "ผู้ช่วย AI", "assistant": "",
"system": "ระบบ" "system": ""
}, },
"aiBeta": "", "aiBeta": "",
"label": "แชท", "label": "",
"menu": "เมนู", "menu": "",
"newChat": "แชทใหม่", "newChat": "",
"deleteChat": "ลบแชท", "deleteChat": "",
"deleteMessage": "ลบข้อความ", "deleteMessage": "",
"viewAsMermaid": "", "viewAsMermaid": "",
"placeholder": { "placeholder": {
"title": "", "title": "",
"description": "", "description": "",
"hint": "" "hint": ""
}, },
"preview": "ดูตัวอย่าง", "preview": "",
"insert": "แทรก", "insert": "",
"retry": "ลองซ้ำ", "retry": "",
"errors": { "errors": {
"promptTooShort": "", "promptTooShort": "",
"promptTooLong": "", "promptTooLong": "",
"generationFailed": "การสร้างล้มเหลว", "generationFailed": "",
"invalidDiagram": "", "invalidDiagram": "",
"fixInMermaid": "", "fixInMermaid": "",
"aiRepair": "", "aiRepair": "",
@@ -682,7 +662,7 @@
"generalRateLimit": "", "generalRateLimit": "",
"messageLimitInputPlaceholder": "" "messageLimitInputPlaceholder": ""
}, },
"upsellBtnLabel": "อัปเกรดบัญชีเป็นแบบ Plus" "upsellBtnLabel": ""
}, },
"quickSearch": { "quickSearch": {
"placeholder": "ค้นหาด่วน" "placeholder": "ค้นหาด่วน"
@@ -721,15 +701,15 @@
"shortcutHint": "" "shortcutHint": ""
}, },
"keys": { "keys": {
"ctrl": "Ctrl", "ctrl": "",
"option": "Option", "option": "",
"cmd": "Cmd", "cmd": "",
"alt": "Alt", "alt": "",
"escape": "Esc", "escape": "",
"enter": "Enter", "enter": "",
"shift": "เลื่อน", "shift": "",
"spacebar": "อวกาศ", "spacebar": "",
"delete": "ลบ", "delete": "",
"mmb": "" "mmb": ""
} }
} }
+47 -67
View File
@@ -3,10 +3,6 @@
"paste": "Yapıştır", "paste": "Yapıştır",
"pasteAsPlaintext": "Düz metin olarak yapıştır", "pasteAsPlaintext": "Düz metin olarak yapıştır",
"pasteCharts": "Grafikleri yapıştır", "pasteCharts": "Grafikleri yapıştır",
"chartType_bar": "",
"chartType_line": "",
"chartType_radar": "",
"chartType_plaintext": "",
"selectAll": "Tümünü seç", "selectAll": "Tümünü seç",
"multiSelect": "Seçime öge ekle", "multiSelect": "Seçime öge ekle",
"moveCanvas": "Tuvali taşı", "moveCanvas": "Tuvali taşı",
@@ -53,14 +49,7 @@
"arrowhead_crowfoot_many": "Karga ayak (çok)", "arrowhead_crowfoot_many": "Karga ayak (çok)",
"arrowhead_crowfoot_one": "Karga ayak (bir)", "arrowhead_crowfoot_one": "Karga ayak (bir)",
"arrowhead_crowfoot_one_or_many": "Karga ayak (bir veya çok sayıda)", "arrowhead_crowfoot_one_or_many": "Karga ayak (bir veya çok sayıda)",
"arrowhead_cardinality_one": "",
"arrowhead_cardinality_many": "",
"arrowhead_cardinality_one_or_many": "",
"arrowhead_cardinality_exactly_one": "",
"arrowhead_cardinality_zero_or_one": "",
"arrowhead_cardinality_zero_or_many": "",
"more_options": "Daha fazla seçenek", "more_options": "Daha fazla seçenek",
"cardinality": "",
"arrowtypes": "Ok şekli", "arrowtypes": "Ok şekli",
"arrowtype_sharp": "Düz ok", "arrowtype_sharp": "Düz ok",
"arrowtype_round": "Kavisli ok", "arrowtype_round": "Kavisli ok",
@@ -128,7 +117,7 @@
"share": "Paylaş", "share": "Paylaş",
"showStroke": "Kontur için renk seçiciyi göster", "showStroke": "Kontur için renk seçiciyi göster",
"showBackground": "Arka plan renk seçicisini göster", "showBackground": "Arka plan renk seçicisini göster",
"showFonts": "Yazı tipi seçiciyi göster", "showFonts": "Yazı tipi seçici",
"toggleTheme": "Aydınlık/karanlık mod", "toggleTheme": "Aydınlık/karanlık mod",
"theme": "Tema", "theme": "Tema",
"personalLib": "Kişisel Kitaplık", "personalLib": "Kişisel Kitaplık",
@@ -182,11 +171,7 @@
"linkToElement": "Nesneye bağlantıla", "linkToElement": "Nesneye bağlantıla",
"wrapSelectionInFrame": "Seçimi karede kaydır", "wrapSelectionInFrame": "Seçimi karede kaydır",
"tab": "Sekme", "tab": "Sekme",
"shapeSwitch": "Şekli başkasıyla değiştir", "shapeSwitch": "Şekli başkasıyla değiştir"
"preferences": "Tercihler",
"preferences_toolLock": "Aracı Kilitle",
"arrowBinding": "",
"midpointSnapping": ""
}, },
"elementLink": { "elementLink": {
"title": "Nesneye bağlantıla", "title": "Nesneye bağlantıla",
@@ -356,7 +341,7 @@
"canvasPanning": "Tuvali taşımak için {{shortcut_1}} kısayolunu basılı tutun, sürüklerken {{shortcut_2}} kısayolunu veya el aracını kullanın", "canvasPanning": "Tuvali taşımak için {{shortcut_1}} kısayolunu basılı tutun, sürüklerken {{shortcut_2}} kısayolunu veya el aracını kullanın",
"linearElement": "Birden fazla nokta için tıklayın, tek çizgi için sürükleyin", "linearElement": "Birden fazla nokta için tıklayın, tek çizgi için sürükleyin",
"arrowTool": "Birden çok nokta başlatmak için tıklayın, tek bir çizgi için sürükleyin. Ok türünü değiştirmek için {{shortcut}} kısayoluna basın.", "arrowTool": "Birden çok nokta başlatmak için tıklayın, tek bir çizgi için sürükleyin. Ok türünü değiştirmek için {{shortcut}} kısayoluna basın.",
"arrowBindModifiers": "Bağlamayı (kenetlenmeyi) devre dışı bırakmak için {{shortcut_1}} tuşuna, sabit bir noktaya bağlamak için {{shortcut_2}} tuşuna basılı tutun.", "arrowBindModifiers": "",
"freeDraw": "Tıkla ve sürükle, bitirdiğinde serbest bırak", "freeDraw": "Tıkla ve sürükle, bitirdiğinde serbest bırak",
"text": "İpucu: seçme aracıyla herhangi bir yere çift tıklayarak da yazı ekleyebilirsin", "text": "İpucu: seçme aracıyla herhangi bir yere çift tıklayarak da yazı ekleyebilirsin",
"embeddable": "Web sitesi yerleştirmek için sürükle bırak", "embeddable": "Web sitesi yerleştirmek için sürükle bırak",
@@ -364,22 +349,22 @@
"text_editing": "Düzenlemeyi bitirmek için {{shortcut_1}} veya {{shortcut_2}} kısayoluna basın", "text_editing": "Düzenlemeyi bitirmek için {{shortcut_1}} veya {{shortcut_2}} kısayoluna basın",
"linearElementMulti": "Bitirmek için son noktaya tıklayın veya {{shortcut_1}} veya {{shortcut_2}} kısayolunu kullanın", "linearElementMulti": "Bitirmek için son noktaya tıklayın veya {{shortcut_1}} veya {{shortcut_2}} kısayolunu kullanın",
"lockAngle": "{{shortcut}} kısayolunu basılı tutarak açıyı kısıtlayabilirsiniz", "lockAngle": "{{shortcut}} kısayolunu basılı tutarak açıyı kısıtlayabilirsiniz",
"resize": "Yeniden boyutlandırırken {{shortcut_1}} tuşuna basılı tutarak oranları koruyabilir, merkezden boyutlandırmak için {{shortcut_2}} tuşuna basılı tutabilirsiniz.", "resize": "",
"resizeImage": "Serbestçe boyutlandırmak için {{shortcut_1}} tuşunu, merkez odaklı boyutlandırmak için {{shortcut_2}} tuşunu basılı tutun.", "resizeImage": "",
"rotate": "Açıları sabitleyerek döndürmek için {{shortcut}} tuşuna basılı tutun.", "rotate": "",
"lineEditor_info": "Noktaları düzenlemek için {{shortcut_1}} tuşuna basılı tutarak çift tıklayın veya {{shortcut_2}} tuşuna basın.", "lineEditor_info": "",
"lineEditor_line_info": "Noktaları düzenlemek için çift tıklayın veya {{shortcut}} tuşuna basın.", "lineEditor_line_info": "",
"lineEditor_pointSelected": "Noktaları (veya noktayı) silmek için {{shortcut_1}}, çoğaltmak için {{shortcut_2}} tuşuna basın veya taşımak için sürükleyin.", "lineEditor_pointSelected": "",
"lineEditor_nothingSelected": "Düzenlemek için bir nokta seçin (çoklu seçim için {{shortcut_1}} tuşuna basılı tutun) veya yeni noktalar eklemek için {{shortcut_2}} tuşuna basarak tıklayın.", "lineEditor_nothingSelected": "",
"publishLibrary": "Kendi kitaplığınızı yayınlayın", "publishLibrary": "Kendi kitaplığınızı yayınlayın",
"bindTextToElement": "Metin eklemek için {{shortcut}} tuşuna basın", "bindTextToElement": "",
"createFlowchart": "Akış şeması oluşturmak için {{shortcut}} tuşuna basın", "createFlowchart": "",
"deepBoxSelect": "Derin seçim yapmak ve sürüklemeyi engellemek için {{shortcut}} tuşuna basılı tutun.", "deepBoxSelect": "",
"eraserRevert": "Silinmek üzere işaretlenen öğeleri geri yüklemek (veya geri döndürmek) için {{shortcut}} tuşuna basılı tutun.", "eraserRevert": "",
"firefox_clipboard_write": "Bu özelliği etkinleştirmek muhtemelen \"dom.events.asyncClipboard.clipboardItem\" bayrağını \"true\" olarak ayarlayarak yapılabilir. Firefox'ta tarayıcı bayraklarını değiştirmek için \"about:config\" sayfasını ziyaret edin.", "firefox_clipboard_write": "Bu özelliği etkinleştirmek muhtemelen \"dom.events.asyncClipboard.clipboardItem\" bayrağını \"true\" olarak ayarlayarak yapılabilir. Firefox'ta tarayıcı bayraklarını değiştirmek için \"about:config\" sayfasını ziyaret edin.",
"disableSnapping": "Hizalamayı (kenetlenmeyi) devre dışı bırakmak için {{shortcut}} tuşuna basılı tutun.", "disableSnapping": "",
"enterCropEditor": "Görseli kırpmak için üzerine çift tıklayın veya {{shortcut}} tuşuna basın.", "enterCropEditor": "",
"leaveCropEditor": "Kırpmayı tamamlamak için görselin dışına tıklayın veya {{shortcut_1}} ya da {{shortcut_2}} tuşuna basın." "leaveCropEditor": ""
}, },
"canvasError": { "canvasError": {
"cannotShowPreview": "Önizleme gösterilemiyor", "cannotShowPreview": "Önizleme gösterilemiyor",
@@ -410,10 +395,6 @@
"errorDialog": { "errorDialog": {
"title": "Hata" "title": "Hata"
}, },
"progressDialog": {
"title": "",
"defaultMessage": ""
},
"exportDialog": { "exportDialog": {
"disk_title": "Belleğe kaydet", "disk_title": "Belleğe kaydet",
"disk_details": "Sahne verilerini daha sonra içe aktarabileceğiniz bir dosyaya aktarın.", "disk_details": "Sahne verilerini daha sonra içe aktarabileceğiniz bir dosyaya aktarın.",
@@ -455,8 +436,8 @@
"toggleElementLock": "Seçimi Kilitle/çöz", "toggleElementLock": "Seçimi Kilitle/çöz",
"movePageUpDown": "Sayfayı yukarı/aşağı kaydır", "movePageUpDown": "Sayfayı yukarı/aşağı kaydır",
"movePageLeftRight": "Sayfayı sola/sağa kaydır", "movePageLeftRight": "Sayfayı sola/sağa kaydır",
"cropStart": "Görseli kırp", "cropStart": "",
"cropFinish": "Görsel kırpmayı tamamla" "cropFinish": ""
}, },
"clearCanvasDialog": { "clearCanvasDialog": {
"title": "Tuvali temizle" "title": "Tuvali temizle"
@@ -547,7 +528,7 @@
"copyStyles": "Stiller kopyalandı.", "copyStyles": "Stiller kopyalandı.",
"copyToClipboard": "Panoya kopyalandı.", "copyToClipboard": "Panoya kopyalandı.",
"copyToClipboardAsPng": "{{exportSelection}} panoya PNG olarak\n({{exportColorScheme}}) kopyalandı", "copyToClipboardAsPng": "{{exportSelection}} panoya PNG olarak\n({{exportColorScheme}}) kopyalandı",
"copyToClipboardAsSvg": "{{exportSelection}} SVG olarak panoya kopyalandı ({{exportColorScheme}})", "copyToClipboardAsSvg": "",
"fileSaved": "Dosya kaydedildi.", "fileSaved": "Dosya kaydedildi.",
"fileSavedToFilename": "{filename} kaydedildi", "fileSavedToFilename": "{filename} kaydedildi",
"canvas": "tuval", "canvas": "tuval",
@@ -555,7 +536,7 @@
"pasteAsSingleElement": "Tekil obje olarak yapıştırmak için veya var olan bir metin editörüne yapıştırmak için {{shortcut}} kullanın", "pasteAsSingleElement": "Tekil obje olarak yapıştırmak için veya var olan bir metin editörüne yapıştırmak için {{shortcut}} kullanın",
"unableToEmbed": "Bu URL'i yerleştirmeye şu anda izin verilmiyor. URL'in beyaz listeye alınmasını istiyorsanız GitHub'da bir issue açın", "unableToEmbed": "Bu URL'i yerleştirmeye şu anda izin verilmiyor. URL'in beyaz listeye alınmasını istiyorsanız GitHub'da bir issue açın",
"unrecognizedLinkFormat": "Yerleştirdiğiniz bağlantı beklenen biçime uymuyor. Lütfen kaynak sitenin sağladığı \"yerleştir\" dizesini yapıştırmayı deneyin", "unrecognizedLinkFormat": "Yerleştirdiğiniz bağlantı beklenen biçime uymuyor. Lütfen kaynak sitenin sağladığı \"yerleştir\" dizesini yapıştırmayı deneyin",
"elementLinkCopied": "Bağlantı panoya kopyalandı" "elementLinkCopied": ""
}, },
"colors": { "colors": {
"transparent": "Şeffaf", "transparent": "Şeffaf",
@@ -576,9 +557,9 @@
}, },
"welcomeScreen": { "welcomeScreen": {
"app": { "app": {
"center_heading": "Çizimleriniz tarayıcınızın depolama alanına kaydedilir.", "center_heading": "",
"center_heading_line2": "Tarayıcı depolama alanı beklenmedik bir şekilde silinebilir.", "center_heading_line2": "",
"center_heading_line3": "Veri kaybını önlemek için çalışmanızı düzenli olarak bir dosyaya kaydedin.", "center_heading_line3": "",
"center_heading_plus": "Ecalidraw+'a mı gitmek istediniz?", "center_heading_plus": "Ecalidraw+'a mı gitmek istediniz?",
"menuHint": "Dışa aktar, seçenekler, diller, ..." "menuHint": "Dışa aktar, seçenekler, diller, ..."
}, },
@@ -590,7 +571,7 @@
} }
}, },
"colorPicker": { "colorPicker": {
"color": "Renk", "color": "",
"mostUsedCustomColors": "En çok kullanılan özel renkler", "mostUsedCustomColors": "En çok kullanılan özel renkler",
"colors": "Renkler", "colors": "Renkler",
"shades": "Tonlar", "shades": "Tonlar",
@@ -631,41 +612,40 @@
"mermaid": { "mermaid": {
"title": "Mermaid'den Excalidraw'a", "title": "Mermaid'den Excalidraw'a",
"button": "Ekle", "button": "Ekle",
"description": "", "description": "Şu anda yalnızca <flowchartLink>Akış şeması</flowchartLink>,<sequenceLink> Dizi, </sequenceLink> ve <classLink>Sınıf </classLink>Diyagramları deskteklenmektedir. Diğer türler, Excalidraw'da görsel olarak çizilecektir.",
"syntax": "Mermaid Sözdizimi", "syntax": "Mermaid Sözdizimi",
"preview": "Önizleme", "preview": "Önizleme",
"label": "Mermaid", "label": "",
"inputPlaceholder": "\"Mermaid diyagram tanımını buraya yazın...", "inputPlaceholder": ""
"autoFixAvailable": ""
}, },
"ttd": { "ttd": {
"error": "Hata!" "error": ""
}, },
"chat": { "chat": {
"inputPlaceholder": "Diyagram fikrinizi buraya yazmaya başlayın... (Yeni satır için {{shortcut}})", "inputPlaceholder": "",
"inputPlaceholderWithMessages": "Diyagramınızı geliştirmeye devam edin...", "inputPlaceholderWithMessages": "",
"generating": "Oluşturuluyor...", "generating": "",
"rateLimitRemaining": "Bugün için {{count}} hak kaldı", "rateLimitRemaining": "",
"role": { "role": {
"user": "Siz", "user": "",
"assistant": "YZ Asistanı", "assistant": "",
"system": "Sistem" "system": ""
}, },
"aiBeta": "YZ Beta", "aiBeta": "",
"label": "Sohbet", "label": "",
"menu": "Menü", "menu": "",
"newChat": "Yeni Sohbet", "newChat": "",
"deleteChat": "Sohbeti sil", "deleteChat": "",
"deleteMessage": "Mesajı sil", "deleteMessage": "",
"viewAsMermaid": "", "viewAsMermaid": "",
"placeholder": { "placeholder": {
"title": "\"Hadi, diyagramınızı tasarlayalım", "title": "",
"description": "Oluşturmak istediğiniz diyagramı tarif edin, sizin için biz hazırlayalım.", "description": "",
"hint": "" "hint": ""
}, },
"preview": "Önizleme", "preview": "",
"insert": "Ekle", "insert": "",
"retry": "Yeniden dene", "retry": "",
"errors": { "errors": {
"promptTooShort": "", "promptTooShort": "",
"promptTooLong": "", "promptTooLong": "",
+31 -51
View File
@@ -3,10 +3,6 @@
"paste": "Вставити", "paste": "Вставити",
"pasteAsPlaintext": "Вставити як текст", "pasteAsPlaintext": "Вставити як текст",
"pasteCharts": "Вставити діаграми", "pasteCharts": "Вставити діаграми",
"chartType_bar": "",
"chartType_line": "",
"chartType_radar": "",
"chartType_plaintext": "",
"selectAll": "Вибрати все", "selectAll": "Вибрати все",
"multiSelect": "Додати елемент до вибраного", "multiSelect": "Додати елемент до вибраного",
"moveCanvas": "Перемістити полотно", "moveCanvas": "Перемістити полотно",
@@ -53,14 +49,7 @@
"arrowhead_crowfoot_many": "", "arrowhead_crowfoot_many": "",
"arrowhead_crowfoot_one": "", "arrowhead_crowfoot_one": "",
"arrowhead_crowfoot_one_or_many": "", "arrowhead_crowfoot_one_or_many": "",
"arrowhead_cardinality_one": "",
"arrowhead_cardinality_many": "",
"arrowhead_cardinality_one_or_many": "",
"arrowhead_cardinality_exactly_one": "",
"arrowhead_cardinality_zero_or_one": "",
"arrowhead_cardinality_zero_or_many": "",
"more_options": "Інші опції", "more_options": "Інші опції",
"cardinality": "",
"arrowtypes": "Тип стрілки", "arrowtypes": "Тип стрілки",
"arrowtype_sharp": "Гостра стрілка", "arrowtype_sharp": "Гостра стрілка",
"arrowtype_round": "Вигнута стрілка", "arrowtype_round": "Вигнута стрілка",
@@ -182,11 +171,7 @@
"linkToElement": "Посилання на об’єкт", "linkToElement": "Посилання на об’єкт",
"wrapSelectionInFrame": "Обтікання виділеного фрагмента рамкою", "wrapSelectionInFrame": "Обтікання виділеного фрагмента рамкою",
"tab": "", "tab": "",
"shapeSwitch": "", "shapeSwitch": ""
"preferences": "",
"preferences_toolLock": "",
"arrowBinding": "",
"midpointSnapping": ""
}, },
"elementLink": { "elementLink": {
"title": "Посилання на об’єкт", "title": "Посилання на об’єкт",
@@ -201,7 +186,7 @@
"inputPlaceholder": "", "inputPlaceholder": "",
"heading": "", "heading": "",
"noResults": "", "noResults": "",
"clearSearch": "Очистити пошук" "clearSearch": ""
} }
}, },
"search": { "search": {
@@ -249,7 +234,7 @@
"clear": "Очистити", "clear": "Очистити",
"remove": "Видалити", "remove": "Видалити",
"embed": "Перемкнути вкладення", "embed": "Перемкнути вкладення",
"publishLibrary": "Перейменувати або опублікувати", "publishLibrary": "",
"submit": "Надіслати", "submit": "Надіслати",
"confirm": "Підтвердити", "confirm": "Підтвердити",
"embeddableInteractionButton": "Натисніть для взаємодії" "embeddableInteractionButton": "Натисніть для взаємодії"
@@ -372,7 +357,7 @@
"lineEditor_pointSelected": "", "lineEditor_pointSelected": "",
"lineEditor_nothingSelected": "", "lineEditor_nothingSelected": "",
"publishLibrary": "Опублікувати свою власну бібліотеку", "publishLibrary": "Опублікувати свою власну бібліотеку",
"bindTextToElement": "{{shortcut}} щоб додати текст", "bindTextToElement": "",
"createFlowchart": "", "createFlowchart": "",
"deepBoxSelect": "", "deepBoxSelect": "",
"eraserRevert": "", "eraserRevert": "",
@@ -410,10 +395,6 @@
"errorDialog": { "errorDialog": {
"title": "Помилка" "title": "Помилка"
}, },
"progressDialog": {
"title": "",
"defaultMessage": ""
},
"exportDialog": { "exportDialog": {
"disk_title": "Зберегти на диск", "disk_title": "Зберегти на диск",
"disk_details": "Експорт даних сцени в файл, з якого можна імпортувати пізніше.", "disk_details": "Експорт даних сцени в файл, з якого можна імпортувати пізніше.",
@@ -590,7 +571,7 @@
} }
}, },
"colorPicker": { "colorPicker": {
"color": "Колір", "color": "",
"mostUsedCustomColors": "Найбільш використовувані користувацькі кольори", "mostUsedCustomColors": "Найбільш використовувані користувацькі кольори",
"colors": "Кольори", "colors": "Кольори",
"shades": "Тіні", "shades": "Тіні",
@@ -631,32 +612,31 @@
"mermaid": { "mermaid": {
"title": "Mermaid у Excalidraw", "title": "Mermaid у Excalidraw",
"button": "Вставити", "button": "Вставити",
"description": "", "description": "Наразі підтримується тільки <flowchartLink>блок-схеми</flowchartLink><sequenceLink>діаграми послідовностей</sequenceLink> та <classLink>діаграми класів</classLink>. Інші типи будуть відображатися як зображення в Excalidraw.",
"syntax": "Синтаксис Mermaid", "syntax": "Синтаксис Mermaid",
"preview": "Попередній перегляд", "preview": "Попередній перегляд",
"label": "", "label": "",
"inputPlaceholder": "", "inputPlaceholder": ""
"autoFixAvailable": ""
}, },
"ttd": { "ttd": {
"error": "Помилка!" "error": ""
}, },
"chat": { "chat": {
"inputPlaceholder": "", "inputPlaceholder": "",
"inputPlaceholderWithMessages": "", "inputPlaceholderWithMessages": "",
"generating": "", "generating": "",
"rateLimitRemaining": "Сьогодні залишилося {{count}} запитів", "rateLimitRemaining": "",
"role": { "role": {
"user": "Ви", "user": "",
"assistant": "ШІ-асистент", "assistant": "",
"system": "Система" "system": ""
}, },
"aiBeta": "", "aiBeta": "",
"label": "Чат", "label": "",
"menu": "Меню", "menu": "",
"newChat": "Новий чат", "newChat": "",
"deleteChat": "Видалити чат", "deleteChat": "",
"deleteMessage": "Видалити повідомлення", "deleteMessage": "",
"viewAsMermaid": "", "viewAsMermaid": "",
"placeholder": { "placeholder": {
"title": "", "title": "",
@@ -664,10 +644,10 @@
"hint": "" "hint": ""
}, },
"preview": "", "preview": "",
"insert": "Вставити", "insert": "",
"retry": "Спробувати знову", "retry": "",
"errors": { "errors": {
"promptTooShort": "Запит надто короткий (мін. {{min}} символів)", "promptTooShort": "",
"promptTooLong": "", "promptTooLong": "",
"generationFailed": "", "generationFailed": "",
"invalidDiagram": "", "invalidDiagram": "",
@@ -680,7 +660,7 @@
"rateLimit": { "rateLimit": {
"messageLimit": "", "messageLimit": "",
"generalRateLimit": "", "generalRateLimit": "",
"messageLimitInputPlaceholder": "Ви досягли вашого ліміту повідомлень" "messageLimitInputPlaceholder": ""
}, },
"upsellBtnLabel": "" "upsellBtnLabel": ""
}, },
@@ -721,15 +701,15 @@
"shortcutHint": "Для панелі команд використовуйте {{shortcut}}" "shortcutHint": "Для панелі команд використовуйте {{shortcut}}"
}, },
"keys": { "keys": {
"ctrl": "Ctrl", "ctrl": "",
"option": "Option", "option": "",
"cmd": "Cmd", "cmd": "",
"alt": "Alt", "alt": "",
"escape": "Esc", "escape": "",
"enter": "Enter", "enter": "",
"shift": "Shift", "shift": "",
"spacebar": "Space", "spacebar": "",
"delete": "Delete", "delete": "",
"mmb": "Коліщатко" "mmb": ""
} }
} }
+2 -22
View File
@@ -3,10 +3,6 @@
"paste": "", "paste": "",
"pasteAsPlaintext": "", "pasteAsPlaintext": "",
"pasteCharts": "", "pasteCharts": "",
"chartType_bar": "",
"chartType_line": "",
"chartType_radar": "",
"chartType_plaintext": "",
"selectAll": "", "selectAll": "",
"multiSelect": "", "multiSelect": "",
"moveCanvas": "", "moveCanvas": "",
@@ -53,14 +49,7 @@
"arrowhead_crowfoot_many": "", "arrowhead_crowfoot_many": "",
"arrowhead_crowfoot_one": "", "arrowhead_crowfoot_one": "",
"arrowhead_crowfoot_one_or_many": "", "arrowhead_crowfoot_one_or_many": "",
"arrowhead_cardinality_one": "",
"arrowhead_cardinality_many": "",
"arrowhead_cardinality_one_or_many": "",
"arrowhead_cardinality_exactly_one": "",
"arrowhead_cardinality_zero_or_one": "",
"arrowhead_cardinality_zero_or_many": "",
"more_options": "", "more_options": "",
"cardinality": "",
"arrowtypes": "", "arrowtypes": "",
"arrowtype_sharp": "", "arrowtype_sharp": "",
"arrowtype_round": "", "arrowtype_round": "",
@@ -182,11 +171,7 @@
"linkToElement": "", "linkToElement": "",
"wrapSelectionInFrame": "", "wrapSelectionInFrame": "",
"tab": "", "tab": "",
"shapeSwitch": "", "shapeSwitch": ""
"preferences": "",
"preferences_toolLock": "",
"arrowBinding": "",
"midpointSnapping": ""
}, },
"elementLink": { "elementLink": {
"title": "", "title": "",
@@ -410,10 +395,6 @@
"errorDialog": { "errorDialog": {
"title": "" "title": ""
}, },
"progressDialog": {
"title": "",
"defaultMessage": ""
},
"exportDialog": { "exportDialog": {
"disk_title": "", "disk_title": "",
"disk_details": "", "disk_details": "",
@@ -635,8 +616,7 @@
"syntax": "", "syntax": "",
"preview": "", "preview": "",
"label": "", "label": "",
"inputPlaceholder": "", "inputPlaceholder": ""
"autoFixAvailable": ""
}, },
"ttd": { "ttd": {
"error": "" "error": ""
+2 -22
View File
@@ -3,10 +3,6 @@
"paste": "Dán", "paste": "Dán",
"pasteAsPlaintext": "Dán kiểu văn bản thuần", "pasteAsPlaintext": "Dán kiểu văn bản thuần",
"pasteCharts": "Dán biểu đồ", "pasteCharts": "Dán biểu đồ",
"chartType_bar": "",
"chartType_line": "",
"chartType_radar": "",
"chartType_plaintext": "",
"selectAll": "Chọn tất cả", "selectAll": "Chọn tất cả",
"multiSelect": "Chọn thêm đối tượng này", "multiSelect": "Chọn thêm đối tượng này",
"moveCanvas": "Di chuyển canvas", "moveCanvas": "Di chuyển canvas",
@@ -53,14 +49,7 @@
"arrowhead_crowfoot_many": "", "arrowhead_crowfoot_many": "",
"arrowhead_crowfoot_one": "", "arrowhead_crowfoot_one": "",
"arrowhead_crowfoot_one_or_many": "", "arrowhead_crowfoot_one_or_many": "",
"arrowhead_cardinality_one": "",
"arrowhead_cardinality_many": "",
"arrowhead_cardinality_one_or_many": "",
"arrowhead_cardinality_exactly_one": "",
"arrowhead_cardinality_zero_or_one": "",
"arrowhead_cardinality_zero_or_many": "",
"more_options": "Tùy chọn khác", "more_options": "Tùy chọn khác",
"cardinality": "",
"arrowtypes": "Loại mũi tên", "arrowtypes": "Loại mũi tên",
"arrowtype_sharp": "Mũi tên nhọn", "arrowtype_sharp": "Mũi tên nhọn",
"arrowtype_round": "Mũi tên cong", "arrowtype_round": "Mũi tên cong",
@@ -182,11 +171,7 @@
"linkToElement": "Liên kết đến đối tượng", "linkToElement": "Liên kết đến đối tượng",
"wrapSelectionInFrame": "Đưa vùng chọn vào khung", "wrapSelectionInFrame": "Đưa vùng chọn vào khung",
"tab": "", "tab": "",
"shapeSwitch": "", "shapeSwitch": ""
"preferences": "",
"preferences_toolLock": "",
"arrowBinding": "",
"midpointSnapping": ""
}, },
"elementLink": { "elementLink": {
"title": "Liên kết đến đối tượng", "title": "Liên kết đến đối tượng",
@@ -410,10 +395,6 @@
"errorDialog": { "errorDialog": {
"title": "Lỗi" "title": "Lỗi"
}, },
"progressDialog": {
"title": "",
"defaultMessage": ""
},
"exportDialog": { "exportDialog": {
"disk_title": "Lưu về máy", "disk_title": "Lưu về máy",
"disk_details": "", "disk_details": "",
@@ -635,8 +616,7 @@
"syntax": "", "syntax": "",
"preview": "", "preview": "",
"label": "", "label": "",
"inputPlaceholder": "", "inputPlaceholder": ""
"autoFixAvailable": ""
}, },
"ttd": { "ttd": {
"error": "" "error": ""
+11 -31
View File
@@ -3,10 +3,6 @@
"paste": "粘贴", "paste": "粘贴",
"pasteAsPlaintext": "粘贴为纯文本", "pasteAsPlaintext": "粘贴为纯文本",
"pasteCharts": "粘贴图表", "pasteCharts": "粘贴图表",
"chartType_bar": "",
"chartType_line": "",
"chartType_radar": "",
"chartType_plaintext": "",
"selectAll": "全部选中", "selectAll": "全部选中",
"multiSelect": "添加元素到选区", "multiSelect": "添加元素到选区",
"moveCanvas": "移动画布", "moveCanvas": "移动画布",
@@ -53,14 +49,7 @@
"arrowhead_crowfoot_many": "鸦爪标记(多)", "arrowhead_crowfoot_many": "鸦爪标记(多)",
"arrowhead_crowfoot_one": "鸦爪标记(一)", "arrowhead_crowfoot_one": "鸦爪标记(一)",
"arrowhead_crowfoot_one_or_many": "鸦爪标记(一或多)", "arrowhead_crowfoot_one_or_many": "鸦爪标记(一或多)",
"arrowhead_cardinality_one": "",
"arrowhead_cardinality_many": "",
"arrowhead_cardinality_one_or_many": "",
"arrowhead_cardinality_exactly_one": "",
"arrowhead_cardinality_zero_or_one": "",
"arrowhead_cardinality_zero_or_many": "",
"more_options": "更多选项", "more_options": "更多选项",
"cardinality": "",
"arrowtypes": "箭头类型", "arrowtypes": "箭头类型",
"arrowtype_sharp": "直箭头", "arrowtype_sharp": "直箭头",
"arrowtype_round": "曲线箭头", "arrowtype_round": "曲线箭头",
@@ -182,11 +171,7 @@
"linkToElement": "链接到对象", "linkToElement": "链接到对象",
"wrapSelectionInFrame": "用选中的元素创建画框", "wrapSelectionInFrame": "用选中的元素创建画框",
"tab": "Tab", "tab": "Tab",
"shapeSwitch": "切换形状", "shapeSwitch": "切换形状"
"preferences": "",
"preferences_toolLock": "",
"arrowBinding": "",
"midpointSnapping": ""
}, },
"elementLink": { "elementLink": {
"title": "链接到对象", "title": "链接到对象",
@@ -410,10 +395,6 @@
"errorDialog": { "errorDialog": {
"title": "错误" "title": "错误"
}, },
"progressDialog": {
"title": "",
"defaultMessage": ""
},
"exportDialog": { "exportDialog": {
"disk_title": "保存到本地", "disk_title": "保存到本地",
"disk_details": "将画布数据导出为文件,以便以后导入", "disk_details": "将画布数据导出为文件,以便以后导入",
@@ -631,12 +612,11 @@
"mermaid": { "mermaid": {
"title": "Mermaid 至 Excalidraw", "title": "Mermaid 至 Excalidraw",
"button": "插入", "button": "插入",
"description": "", "description": "目前仅支持<flowchartLink>流程图</flowchartLink>、<sequenceLink>序列图</sequenceLink>和<classLink>类图</classLink>。其他类型在 Excalidraw 中将以图像呈现。",
"syntax": "Mermaid 语法", "syntax": "Mermaid 语法",
"preview": "预览", "preview": "预览",
"label": "Mermaid", "label": "",
"inputPlaceholder": "", "inputPlaceholder": ""
"autoFixAvailable": ""
}, },
"ttd": { "ttd": {
"error": "" "error": ""
@@ -673,16 +653,16 @@
"invalidDiagram": "", "invalidDiagram": "",
"fixInMermaid": "", "fixInMermaid": "",
"aiRepair": "", "aiRepair": "",
"requestAborted": "请求中止", "requestAborted": "",
"requestFailed": "请求失败", "requestFailed": "",
"mermaidParseError": "Mermaid 语法错误" "mermaidParseError": ""
}, },
"rateLimit": { "rateLimit": {
"messageLimit": "您已达到免费版的 AI 使用上限。请尝试 Excalidraw+ 获取更多额度,或明天再试。", "messageLimit": "",
"generalRateLimit": "慢点慢点,您的手速太快了!请稍候再试。", "generalRateLimit": "",
"messageLimitInputPlaceholder": "您已达到消息上限" "messageLimitInputPlaceholder": ""
}, },
"upsellBtnLabel": "升级到 Plus" "upsellBtnLabel": ""
}, },
"quickSearch": { "quickSearch": {
"placeholder": "快速搜索" "placeholder": "快速搜索"
+2 -22
View File
@@ -3,10 +3,6 @@
"paste": "貼上", "paste": "貼上",
"pasteAsPlaintext": "", "pasteAsPlaintext": "",
"pasteCharts": "貼上圖表", "pasteCharts": "貼上圖表",
"chartType_bar": "",
"chartType_line": "",
"chartType_radar": "",
"chartType_plaintext": "",
"selectAll": "全選", "selectAll": "全選",
"multiSelect": "多重選取", "multiSelect": "多重選取",
"moveCanvas": "移動畫布", "moveCanvas": "移動畫布",
@@ -53,14 +49,7 @@
"arrowhead_crowfoot_many": "", "arrowhead_crowfoot_many": "",
"arrowhead_crowfoot_one": "", "arrowhead_crowfoot_one": "",
"arrowhead_crowfoot_one_or_many": "", "arrowhead_crowfoot_one_or_many": "",
"arrowhead_cardinality_one": "",
"arrowhead_cardinality_many": "",
"arrowhead_cardinality_one_or_many": "",
"arrowhead_cardinality_exactly_one": "",
"arrowhead_cardinality_zero_or_one": "",
"arrowhead_cardinality_zero_or_many": "",
"more_options": "", "more_options": "",
"cardinality": "",
"arrowtypes": "", "arrowtypes": "",
"arrowtype_sharp": "", "arrowtype_sharp": "",
"arrowtype_round": "", "arrowtype_round": "",
@@ -182,11 +171,7 @@
"linkToElement": "", "linkToElement": "",
"wrapSelectionInFrame": "", "wrapSelectionInFrame": "",
"tab": "", "tab": "",
"shapeSwitch": "", "shapeSwitch": ""
"preferences": "",
"preferences_toolLock": "",
"arrowBinding": "",
"midpointSnapping": ""
}, },
"elementLink": { "elementLink": {
"title": "", "title": "",
@@ -410,10 +395,6 @@
"errorDialog": { "errorDialog": {
"title": "" "title": ""
}, },
"progressDialog": {
"title": "",
"defaultMessage": ""
},
"exportDialog": { "exportDialog": {
"disk_title": "", "disk_title": "",
"disk_details": "", "disk_details": "",
@@ -635,8 +616,7 @@
"syntax": "", "syntax": "",
"preview": "", "preview": "",
"label": "", "label": "",
"inputPlaceholder": "", "inputPlaceholder": ""
"autoFixAvailable": ""
}, },
"ttd": { "ttd": {
"error": "" "error": ""
+87 -107
View File
@@ -3,10 +3,6 @@
"paste": "貼上", "paste": "貼上",
"pasteAsPlaintext": "以純文字貼上", "pasteAsPlaintext": "以純文字貼上",
"pasteCharts": "貼上圖表", "pasteCharts": "貼上圖表",
"chartType_bar": "長條圖",
"chartType_line": "折線圖",
"chartType_radar": "雷達圖",
"chartType_plaintext": "純文字",
"selectAll": "全選", "selectAll": "全選",
"multiSelect": "將物件加入選取範圍", "multiSelect": "將物件加入選取範圍",
"moveCanvas": "移動畫布", "moveCanvas": "移動畫布",
@@ -53,14 +49,7 @@
"arrowhead_crowfoot_many": "雞爪符號(多)", "arrowhead_crowfoot_many": "雞爪符號(多)",
"arrowhead_crowfoot_one": "雞爪符號(一)", "arrowhead_crowfoot_one": "雞爪符號(一)",
"arrowhead_crowfoot_one_or_many": "雞爪符號(一或多)", "arrowhead_crowfoot_one_or_many": "雞爪符號(一或多)",
"arrowhead_cardinality_one": "",
"arrowhead_cardinality_many": "",
"arrowhead_cardinality_one_or_many": "",
"arrowhead_cardinality_exactly_one": "",
"arrowhead_cardinality_zero_or_one": "",
"arrowhead_cardinality_zero_or_many": "",
"more_options": "更多選項", "more_options": "更多選項",
"cardinality": "",
"arrowtypes": "箭頭類型", "arrowtypes": "箭頭類型",
"arrowtype_sharp": "尖銳箭頭", "arrowtype_sharp": "尖銳箭頭",
"arrowtype_round": "彎角箭頭", "arrowtype_round": "彎角箭頭",
@@ -153,8 +142,8 @@
"editArrow": "編輯箭頭" "editArrow": "編輯箭頭"
}, },
"polygon": { "polygon": {
"breakPolygon": "解除多邊形", "breakPolygon": "",
"convertToPolygon": "轉換為多邊形" "convertToPolygon": ""
}, },
"elementLock": { "elementLock": {
"lock": "鎖定", "lock": "鎖定",
@@ -181,12 +170,8 @@
"copyElementLink": "複製此物件的連結", "copyElementLink": "複製此物件的連結",
"linkToElement": "連結至物件", "linkToElement": "連結至物件",
"wrapSelectionInFrame": "將選取內容放入框架", "wrapSelectionInFrame": "將選取內容放入框架",
"tab": "Tab", "tab": "",
"shapeSwitch": "切換形狀", "shapeSwitch": ""
"preferences": "偏好設定",
"preferences_toolLock": "鎖定工具",
"arrowBinding": "箭頭連結",
"midpointSnapping": "貼齊中點"
}, },
"elementLink": { "elementLink": {
"title": "連結至物件", "title": "連結至物件",
@@ -198,10 +183,10 @@
"hint_emptyLibrary": "選取畫布上的物件以加入,或從下方的公開儲存庫中安裝資料庫。", "hint_emptyLibrary": "選取畫布上的物件以加入,或從下方的公開儲存庫中安裝資料庫。",
"hint_emptyPrivateLibrary": "選擇畫布上的物件以在此加入。", "hint_emptyPrivateLibrary": "選擇畫布上的物件以在此加入。",
"search": { "search": {
"inputPlaceholder": "搜尋資料庫", "inputPlaceholder": "",
"heading": "相符的資料庫", "heading": "",
"noResults": "找不到相符的項目...", "noResults": "",
"clearSearch": "清除搜尋" "clearSearch": ""
} }
}, },
"search": { "search": {
@@ -210,8 +195,8 @@
"singleResult": "結果", "singleResult": "結果",
"multipleResults": "結果", "multipleResults": "結果",
"placeholder": "在畫布上尋找文字…", "placeholder": "在畫布上尋找文字…",
"frames": "框架", "frames": "",
"texts": "文字" "texts": ""
}, },
"buttons": { "buttons": {
"clearReset": "重設畫布", "clearReset": "重設畫布",
@@ -245,11 +230,11 @@
"objectsSnapMode": "吸附至物件", "objectsSnapMode": "吸附至物件",
"exitZenMode": "離開專注模式", "exitZenMode": "離開專注模式",
"cancel": "取消", "cancel": "取消",
"saveLibNames": "儲存名稱並離開", "saveLibNames": "",
"clear": "清除", "clear": "清除",
"remove": "刪除", "remove": "刪除",
"embed": "切換嵌入", "embed": "切換嵌入",
"publishLibrary": "重新命名或發布", "publishLibrary": "",
"submit": "送出", "submit": "送出",
"confirm": "確認", "confirm": "確認",
"embeddableInteractionButton": "點擊以互動" "embeddableInteractionButton": "點擊以互動"
@@ -276,7 +261,7 @@
"removeItemsFromsLibrary": "從資料庫刪除 {{count}} 項?", "removeItemsFromsLibrary": "從資料庫刪除 {{count}} 項?",
"invalidEncryptionKey": "加密鍵必須為22字元。即時協作已停用。", "invalidEncryptionKey": "加密鍵必須為22字元。即時協作已停用。",
"collabOfflineWarning": "沒有可用的網路連線。\n變更無法儲存!", "collabOfflineWarning": "沒有可用的網路連線。\n變更無法儲存!",
"localStorageQuotaExceeded": "瀏覽器儲存空間已滿。變更將不會被儲存。" "localStorageQuotaExceeded": ""
}, },
"errors": { "errors": {
"unsupportedFileType": "不支援的檔案類型。", "unsupportedFileType": "不支援的檔案類型。",
@@ -307,7 +292,7 @@
}, },
"toolBar": { "toolBar": {
"selection": "選取", "selection": "選取",
"lasso": "繩索選取", "lasso": "",
"image": "插入圖片", "image": "插入圖片",
"rectangle": "長方形", "rectangle": "長方形",
"diamond": "菱形", "diamond": "菱形",
@@ -328,7 +313,7 @@
"hand": "手形(平移工具)", "hand": "手形(平移工具)",
"extraTools": "更多工具", "extraTools": "更多工具",
"mermaidToExcalidraw": "Mermaid 至 Excalidraw", "mermaidToExcalidraw": "Mermaid 至 Excalidraw",
"convertElementType": "切換形狀類型" "convertElementType": ""
}, },
"element": { "element": {
"rectangle": "矩形", "rectangle": "矩形",
@@ -352,34 +337,34 @@
"shapes": "形狀" "shapes": "形狀"
}, },
"hints": { "hints": {
"dismissSearch": "{{shortcut}} 以隱藏搜尋", "dismissSearch": "",
"canvasPanning": "如要移動畫布,請在拖曳時按住 {{shortcut_1}} 或 {{shortcut_2}},或使用手形工具", "canvasPanning": "",
"linearElement": "點擊以繪製多點曲線;或拖曳以繪製直線", "linearElement": "點擊以繪製多點曲線;或拖曳以繪製直線",
"arrowTool": "點選以開始建立多點,拖曳可建立單一線段。再次按下 {{shortcut}} 以變更箭頭類型。", "arrowTool": "",
"arrowBindModifiers": "按住 {{shortcut_1}} 以停用綁定,或按住 {{shortcut_2}} 以綁定於固定點", "arrowBindModifiers": "",
"freeDraw": "點擊並拖曳來繪圖,放開即結束", "freeDraw": "點擊並拖曳來繪圖,放開即結束",
"text": "提示:亦可使用選取工具在任何地方雙擊來加入文字", "text": "提示:亦可使用選取工具在任何地方雙擊來加入文字",
"embeddable": "點擊並拖移以建立嵌入網站", "embeddable": "點擊並拖移以建立嵌入網站",
"text_selected": "按兩下滑鼠或按 {{shortcut}} 以編輯文字", "text_selected": "",
"text_editing": "{{shortcut_1}} 或 {{shortcut_2}} 以結束編輯", "text_editing": "",
"linearElementMulti": "點選最後一個點,或按下 {{shortcut_1}} 或 {{shortcut_2}} 以完成", "linearElementMulti": "",
"lockAngle": "你可以按住 {{shortcut}} 以鎖定角度", "lockAngle": "",
"resize": "縮放時按住 {{shortcut_1}} 可保持等比例,\n按住 {{shortcut_2}} 則可從中心縮放", "resize": "",
"resizeImage": "按住 {{shortcut_1}} 可自由縮放,\n按住 {{shortcut_2}} 則可從中心縮放", "resizeImage": "",
"rotate": "你可以在旋轉時按住 {{shortcut}} 以鎖定角度", "rotate": "",
"lineEditor_info": "按住 {{shortcut_1}} 並按兩下或按下 {{shortcut_2}} 以編輯點", "lineEditor_info": "",
"lineEditor_line_info": "按兩下或按 {{shortcut}} 以編輯點", "lineEditor_line_info": "",
"lineEditor_pointSelected": "按下 {{shortcut_1}} 移除點,\n{{shortcut_2}} 重製,或拖曳以移動", "lineEditor_pointSelected": "",
"lineEditor_nothingSelected": "選取一個點以進行編輯(按住 {{shortcut_1}} 可多選),\n或按住 {{shortcut_2}} 並點選以新增點", "lineEditor_nothingSelected": "",
"publishLibrary": "發布個人資料庫", "publishLibrary": "發布個人資料庫",
"bindTextToElement": "按下 {{shortcut}} 新增文字", "bindTextToElement": "",
"createFlowchart": "按下 {{shortcut}} 建立流程圖", "createFlowchart": "",
"deepBoxSelect": "按住 {{shortcut}} 以進行深度選取,並防止拖曳", "deepBoxSelect": "",
"eraserRevert": "按住 {{shortcut}} 以還原標記為刪除的元素", "eraserRevert": "",
"firefox_clipboard_write": "此功能有機會透過將 \"dom.events.asyncClipboard.clipboardItem\" 設定為 \"true\" 來開啟。\n若要變更 Firefox 瀏覽器的此設定值,請至 \"about:config\" 頁面。", "firefox_clipboard_write": "此功能有機會透過將 \"dom.events.asyncClipboard.clipboardItem\" 設定為 \"true\" 來開啟。\n若要變更 Firefox 瀏覽器的此設定值,請至 \"about:config\" 頁面。",
"disableSnapping": "按住 {{shortcut}} 以停用貼齊(自動對齊)", "disableSnapping": "",
"enterCropEditor": "按兩下圖片或按下 {{shortcut}} 以裁剪圖片", "enterCropEditor": "",
"leaveCropEditor": "點選圖片外部,或按下 {{shortcut_1}} 或 {{shortcut_2}} 以完成裁剪" "leaveCropEditor": ""
}, },
"canvasError": { "canvasError": {
"cannotShowPreview": "無法顯示預覽", "cannotShowPreview": "無法顯示預覽",
@@ -410,10 +395,6 @@
"errorDialog": { "errorDialog": {
"title": "錯誤" "title": "錯誤"
}, },
"progressDialog": {
"title": "儲存中",
"defaultMessage": "正在準備儲存..."
},
"exportDialog": { "exportDialog": {
"disk_title": "儲存至硬碟", "disk_title": "儲存至硬碟",
"disk_details": "將場景匯出為可供匯入之檔案", "disk_details": "將場景匯出為可供匯入之檔案",
@@ -576,9 +557,9 @@
}, },
"welcomeScreen": { "welcomeScreen": {
"app": { "app": {
"center_heading": "你的繪圖已儲存在瀏覽器的儲存空間中。", "center_heading": "",
"center_heading_line2": "瀏覽器儲存空間可能會意外地被清除。", "center_heading_line2": "",
"center_heading_line3": "請定期將作品儲存為檔案,以避免遺失。", "center_heading_line3": "",
"center_heading_plus": "您是否是要前往 Excalidraw+ ", "center_heading_plus": "您是否是要前往 Excalidraw+ ",
"menuHint": "輸出、偏好設定、語言..." "menuHint": "輸出、偏好設定、語言..."
}, },
@@ -590,7 +571,7 @@
} }
}, },
"colorPicker": { "colorPicker": {
"color": "顏色", "color": "",
"mostUsedCustomColors": "最常使用的自訂顏色", "mostUsedCustomColors": "最常使用的自訂顏色",
"colors": "顏色", "colors": "顏色",
"shades": "漸變色", "shades": "漸變色",
@@ -631,58 +612,57 @@
"mermaid": { "mermaid": {
"title": "Mermaid 至 Excalidraw", "title": "Mermaid 至 Excalidraw",
"button": "插入", "button": "插入",
"description": "", "description": "目前僅支援 <flowchartLink>Flowchart</flowchartLink> 、 <sequenceLink>Sequence</sequenceLink> 及 <classLink>Class </classLink> 圖表。其餘檔案類型在 Excalidraw 將會以圖像呈現。",
"syntax": "Mermaid 語法", "syntax": "Mermaid 語法",
"preview": "預覽", "preview": "預覽",
"label": "Mermaid", "label": "",
"inputPlaceholder": "在這裡編寫 Mermaid 定義...", "inputPlaceholder": ""
"autoFixAvailable": "自動修正可用"
}, },
"ttd": { "ttd": {
"error": "錯誤!" "error": ""
}, },
"chat": { "chat": {
"inputPlaceholder": "在這裡開始輸入你的圖表構想...({{shortcut}} 換行)", "inputPlaceholder": "",
"inputPlaceholderWithMessages": "繼續調整你的圖表...", "inputPlaceholderWithMessages": "",
"generating": "生成中...", "generating": "",
"rateLimitRemaining": "今日剩餘 {{count}} 次請求", "rateLimitRemaining": "",
"role": { "role": {
"user": "", "user": "",
"assistant": "AI 助理", "assistant": "",
"system": "系統" "system": ""
}, },
"aiBeta": "AI Beta 版", "aiBeta": "",
"label": "對話", "label": "",
"menu": "選單", "menu": "",
"newChat": "新的對話", "newChat": "",
"deleteChat": "刪除對話", "deleteChat": "",
"deleteMessage": "刪除訊息", "deleteMessage": "",
"viewAsMermaid": "以 Mermaid 格式檢視", "viewAsMermaid": "",
"placeholder": { "placeholder": {
"title": "讓我們開始設計你的圖表", "title": "",
"description": "描述你想要建立的圖表,我們將為你生成。", "description": "",
"hint": "" "hint": ""
}, },
"preview": "預覽", "preview": "",
"insert": "插入", "insert": "",
"retry": "重試", "retry": "",
"errors": { "errors": {
"promptTooShort": "提示詞太短(至少 {{min}} 個字元)", "promptTooShort": "",
"promptTooLong": "提示詞太長(最多 {{max}} 個字元)", "promptTooLong": "",
"generationFailed": "生成失敗", "generationFailed": "",
"invalidDiagram": "生成的圖表語法無效 :(。你可以手動編輯、嘗試自動修復,或換個提示詞試試。", "invalidDiagram": "",
"fixInMermaid": "手動編輯 Mermaid →", "fixInMermaid": "",
"aiRepair": "重新生成(自動修復)→", "aiRepair": "",
"requestAborted": "請求已中止", "requestAborted": "",
"requestFailed": "請求失敗", "requestFailed": "",
"mermaidParseError": "Mermaid 語法錯誤" "mermaidParseError": ""
}, },
"rateLimit": { "rateLimit": {
"messageLimit": "你已達到免費方案的 AI 使用上限。請試用 Excalidraw+ 以取得更多額度,或明天再試。", "messageLimit": "",
"generalRateLimit": "別心急,你的操作速度太快了!請稍等片刻後再試。", "generalRateLimit": "",
"messageLimitInputPlaceholder": "你已達到訊息上限" "messageLimitInputPlaceholder": ""
}, },
"upsellBtnLabel": "升級至 Plus" "upsellBtnLabel": ""
}, },
"quickSearch": { "quickSearch": {
"placeholder": "快速搜尋" "placeholder": "快速搜尋"
@@ -721,15 +701,15 @@
"shortcutHint": "使用 {{shortcut}} 開啟指令面板" "shortcutHint": "使用 {{shortcut}} 開啟指令面板"
}, },
"keys": { "keys": {
"ctrl": "Ctrl", "ctrl": "",
"option": "Option", "option": "",
"cmd": "Cmd", "cmd": "",
"alt": "Alt", "alt": "",
"escape": "Esc", "escape": "",
"enter": "Enter", "enter": "",
"shift": "Shift", "shift": "",
"spacebar": "空白鍵", "spacebar": "",
"delete": "Delete", "delete": "",
"mmb": "滾輪" "mmb": ""
} }
} }

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