Variables: art on a locked artboard is not bound or rewritten by a data set

Squashed from #5118 onto main.
This commit is contained in:
dotCooCoo
2026-11-02 15:21:58 +07:00
committed by bflatastic
parent 30dd4fe8f5
commit e68bf6af55
25 changed files with 158 additions and 30 deletions
+42 -15
View File
@@ -6,7 +6,7 @@ use std::collections::{BTreeMap, BTreeSet};
use serde::{Deserialize, Serialize};
use super::{Document, NodeId, NodeKind, TextKind};
use super::{Document, LockedArtboards, NodeId, NodeKind, TextKind};
/// What a variable drives.
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
@@ -190,17 +190,32 @@ impl Document {
}
/// Whether a variable may be bound to the object `id`: it is in the document, neither it nor
/// anything above it is locked, and nothing above it is hidden. Its own visibility doesn't
/// count, as that is what a visibility variable drives.
/// anything above it is locked, nothing above it is hidden, and it is not on a locked artboard
/// ([`Document::on_locked_artboard`]). Its own visibility doesn't count, as that is what a
/// visibility variable drives.
pub fn variable_target(&self, id: NodeId) -> bool {
self.ancestry(id).is_some_and(|a| a.iter().all(|i| self.node(*i).is_some_and(|n| !n.locked && (n.visible || *i == id))))
self.variable_target_with(&self.locked_artboards(), id)
}
/// Whether a data set reads and rewrites the bound object `id`: it is in the document and
/// neither it nor anything above it is locked. Hidden objects count, and so do objects in a
/// hidden layer or group.
/// [`Document::variable_target`] with the locked artboards `locks` of this document, measured
/// once for many ids.
pub fn variable_target_with(&self, locks: &LockedArtboards, id: NodeId) -> bool {
self.ancestry(id).is_some_and(|a| a.iter().all(|i| self.node(*i).is_some_and(|n| !n.locked && (n.visible || *i == id))))
&& !locks.holds_id(id)
}
/// Whether a data set reads and rewrites the bound object `id`: it is in the document, neither
/// it nor anything above it is locked, and it is not on a locked artboard
/// ([`Document::on_locked_artboard`]). Hidden objects count, and so do objects in a hidden
/// layer or group.
pub fn dataset_target(&self, id: NodeId) -> bool {
self.ancestry(id).is_some_and(|a| a.iter().all(|i| self.node(*i).is_some_and(|n| !n.locked)))
self.dataset_target_with(&self.locked_artboards(), id)
}
/// [`Document::dataset_target`] with the locked artboards `locks` of this document, measured
/// once for many ids.
pub fn dataset_target_with(&self, locks: &LockedArtboards, id: NodeId) -> bool {
self.ancestry(id).is_some_and(|a| a.iter().all(|i| self.node(*i).is_some_and(|n| !n.locked))) && !locks.holds_id(id)
}
/// The type objects of the story that the type object `id` belongs to, in thread order: the
@@ -228,21 +243,32 @@ impl Document {
/// Whether a data set reads and rewrites the text of the type object `id`: every frame of its
/// story ([`Document::story_of`]) is a [`Document::dataset_target`].
pub fn story_target(&self, id: NodeId) -> bool {
self.story_of(id).into_iter().all(|f| self.dataset_target(f))
self.story_target_with(&self.locked_artboards(), id)
}
/// [`Document::story_target`] with the locked artboards `locks` of this document, measured
/// once for many ids.
pub fn story_target_with(&self, locks: &LockedArtboards, id: NodeId) -> bool {
self.story_of(id).into_iter().all(|f| self.dataset_target_with(locks, f))
}
/// What the object `id` holds for the variable of `kind`: its characters (the whole story
/// for a frame of threaded text), whether it shows, or a linked image's path. `None` when the
/// object is gone, is not of that kind, has no link path yet (an embedded image), or is locked
/// or in a locked layer or group, or for text when a frame of its story is (the document's
/// value is whatever it was left at).
/// object is gone, is not of that kind, has no link path yet (an embedded image), or is locked,
/// in a locked layer or group, or on a locked artboard, or for text when a frame of its story
/// is (the document's value is whatever it was left at).
pub fn variable_value(&self, id: NodeId, kind: VariableKind) -> Option<DataValue> {
if !self.dataset_target(id) {
self.variable_value_with(&self.locked_artboards(), id, kind)
}
/// [`Document::variable_value`] with the locked artboards `locks` of this document.
fn variable_value_with(&self, locks: &LockedArtboards, id: NodeId, kind: VariableKind) -> Option<DataValue> {
if !self.dataset_target_with(locks, id) {
return None;
}
let node = self.node(id)?;
match (kind, &node.kind) {
(VariableKind::Text, NodeKind::Text(_)) if self.story_target(id) => Some(DataValue::Text(self.story_text(id))),
(VariableKind::Text, NodeKind::Text(_)) if self.story_target_with(locks, id) => Some(DataValue::Text(self.story_text(id))),
(VariableKind::Visibility, _) => Some(DataValue::Visible(node.visible)),
(VariableKind::Image, NodeKind::Image(im)) => im.link.as_ref().map(|l| DataValue::Image(l.path.clone())),
(VariableKind::Graph, _) => node.extras().graph.as_ref().map(|g| DataValue::Graph(g.to_csv())),
@@ -257,10 +283,11 @@ impl Document {
/// still matches what it says.
pub fn captured_values(&self) -> BTreeMap<String, DataValue> {
let mut out = BTreeMap::new();
let locks = self.locked_artboards();
for v in &self.variables.variables {
// An object driven by several variables of the same kind reads from the first one
// bound, so a capture is one value per variable and applies back the same way.
let value = self.variables.objects_of(&v.name).into_iter().find_map(|id| self.variable_value(id, v.kind));
let value = self.variables.objects_of(&v.name).into_iter().find_map(|id| self.variable_value_with(&locks, id, v.kind));
if let Some(value) = value {
out.insert(v.name.clone(), value);
}
+31 -13
View File
@@ -138,13 +138,15 @@ fn names_param(p: &Value, cmd: &str, fallback: Option<String>, nothing: &str) ->
}
}
/// Refuse what a variable of `kind` can't be bound to: art that is locked or on a hidden or locked
/// layer; a text variable only drives type; an image variable only drives an image object.
/// Refuse what a variable of `kind` can't be bound to: art that is locked, on a hidden or locked
/// layer, or on a locked artboard; a text variable only drives type; an image variable only drives
/// an image object.
fn check_bindable(doc: &vectorcraft_doc::Document, ids: &[NodeId], kind: VariableKind, cmd: &str) -> Result<()> {
let locks = doc.locked_artboards();
for id in ids {
match doc.node(*id) {
None => return Err(EngineError::NoNode(*id)),
Some(_) if !doc.variable_target(*id) => return Err(bad(cmd, not_a_target(doc, *id))),
Some(_) if !doc.variable_target_with(&locks, *id) => return Err(bad(cmd, not_a_target(doc, *id))),
Some(n) if kind == VariableKind::Text && !matches!(n.kind, NodeKind::Text(_)) => {
return Err(bad(cmd, format!("node {} is not type", id.0)));
}
@@ -161,7 +163,7 @@ fn check_bindable(doc: &vectorcraft_doc::Document, ids: &[NodeId], kind: Variabl
}
/// Why `variable_target` refuses `id`: the object is locked, a group or layer that holds it is
/// locked, or one that holds it is hidden, checked in that order.
/// locked, one that holds it is hidden, or it is on a locked artboard, checked in that order.
fn not_a_target(doc: &vectorcraft_doc::Document, id: NodeId) -> String {
let holders: Vec<&vectorcraft_doc::Node> =
doc.ancestry(id).unwrap_or_default().into_iter().filter(|i| *i != id).filter_map(|i| doc.node(i)).collect();
@@ -169,8 +171,10 @@ fn not_a_target(doc: &vectorcraft_doc::Document, id: NodeId) -> String {
format!("node {} is locked", id.0)
} else if holders.iter().any(|n| n.locked) {
format!("node {} is in a locked group or layer", id.0)
} else {
} else if holders.iter().any(|n| !n.visible) {
format!("node {} is in a hidden group or layer", id.0)
} else {
format!("node {} is on a locked artboard", id.0)
}
}
@@ -483,7 +487,7 @@ fn dataset_capture(s: &mut Session, p: &Value) -> Result<Value> {
/// Update Data Set: write what the bound objects hold now into the row that is active, for each
/// variable the row holds. A variable whose objects report no value (locked, inside a locked
/// layer or group, or gone) keeps the row's value. With `all`, every other variable the
/// layer or group, on a locked artboard, or gone) keeps the row's value. With `all`, every other variable the
/// objects report a value for is added to the row. Without an active row there is nothing to
/// update, so say so rather than picking one. With every bound object locked, no value is
/// written; an update that writes no value adds no undo step.
@@ -557,6 +561,20 @@ fn apply_dataset(s: &mut Session, name: &str) -> Result<Value> {
for v in &d.variables.variables {
pairs.extend(d.variables.objects_of(&v.name).into_iter().map(|id| (id, v.name.clone())));
}
// Which bound objects the row may rewrite, measured once before any of them changes, so
// text that grows onto a locked artboard part way through is still rewritten. Each id is
// keyed by whether a text value is meant for it, which checks every frame of its story.
let targets: BTreeSet<(NodeId, bool)> = {
let locks = d.locked_artboards();
let mut out = BTreeSet::new();
for (id, var) in &pairs {
let text = d.variables.variable(var).is_some_and(|v| v.kind == VariableKind::Text);
if if text { d.story_target_with(&locks, *id) } else { d.dataset_target_with(&locks, *id) } {
out.insert((*id, text));
}
}
out
};
// Whether an object is bound to a variable that this row has a value for (the reply's `warning`).
let bound = pairs.iter().any(|(_, var)| ds.values.contains_key(var));
let mut applied = 0usize;
@@ -574,12 +592,12 @@ fn apply_dataset(s: &mut Session, name: &str) -> Result<Value> {
continue;
}
};
// Locked art, art in a locked layer or group, and text whose object is gone, can't be
// rewritten: skipped and counted, like the rest. Hidden art is rewritten, in a hidden
// layer or group too, and stays hidden unless a visibility value shows it. A text value
// rewrites the whole story of threaded text, so it skips when any frame of it is locked.
let target = if kind == VariableKind::Text { d.story_target(id) } else { d.dataset_target(id) };
if !target {
// Locked art, art in a locked layer or group or on a locked artboard, and text whose
// object is gone, can't be rewritten: skipped and counted, like the rest. Hidden art
// is rewritten, in a hidden layer or group too, and stays hidden unless a visibility
// value shows it. A text value rewrites the whole story of threaded text, so it skips
// when any frame of it is locked or on a locked artboard.
if !targets.contains(&(id, kind == VariableKind::Text)) {
skipped += 1;
continue;
}
@@ -772,7 +790,7 @@ pub fn specs() -> Vec<CommandSpec> {
"Update Data Set",
["Window", "Variables"],
None,
"{all?: bool} write what the bound objects hold now into the active dataset, for each variable the dataset holds; a variable whose objects report no value (locked, inside a locked layer or group, or gone) keeps the dataset's value. `all: true` also adds every other variable the objects report a value for; `left` names the variables it didn't write → {values, left}",
"{all?: bool} write what the bound objects hold now into the active dataset, for each variable the dataset holds; a variable whose objects report no value (locked, inside a locked layer or group, on a locked artboard, or gone) keeps the dataset's value. `all: true` also adds every other variable the objects report a value for; `left` names the variables it didn't write → {values, left}",
has_doc,
dataset_update
),
+62
View File
@@ -438,6 +438,68 @@ fn locked_art_is_neither_bound_nor_rewritten() {
assert!(!s.doc().unwrap().doc.node(r).unwrap().visible, "the unlocked rectangle still applied");
}
/// The art on a locked artboard acts as locked art: a data set skips it, Update Data Set reads
/// nothing from it, and it takes no new binding. Unlocking the artboard lets the data set rewrite it.
#[test]
fn art_on_a_locked_artboard_is_neither_bound_nor_rewritten() {
let mut s = session();
let t = NodeId(s.execute("text.create", &json!({"x": 2050, "y": 50, "text": "cat"})).unwrap()["id"].as_u64().unwrap());
let fresh = NodeId(s.execute("text.create", &json!({"x": 2100, "y": 100, "text": "new"})).unwrap()["id"].as_u64().unwrap());
let r = rect(&mut s);
s.execute("artboard.new", &json!({"x": 2000, "y": 0, "width": 400, "height": 400})).unwrap();
s.execute("variable.define", &json!({"name": "Name", "kind": "text"})).unwrap();
s.execute("variable.define", &json!({"name": "Show", "kind": "visibility"})).unwrap();
s.execute("variable.define", &json!({"name": "Box", "kind": "visibility"})).unwrap();
s.execute("variable.bind", &json!({"variable": "Name", "ids": [t.0]})).unwrap();
s.execute("variable.bind", &json!({"variable": "Show", "ids": [t.0]})).unwrap();
s.execute("variable.bind", &json!({"variable": "Box", "ids": [r.0]})).unwrap();
s.execute("dataset.capture", &json!({"name": "A"})).unwrap();
s.execute("dataset.new", &json!({"name": "B", "values": {"Name": "Bob", "Show": false, "Box": false}})).unwrap();
s.execute("select.none", &json!({})).unwrap();
s.execute("artboard.setProps", &json!({"index": 1, "locked": true})).unwrap();
let e = s.execute("variable.bind", &json!({"variable": "Name", "ids": [fresh.0]})).unwrap_err().to_string();
assert!(e.contains(&format!("node {} is on a locked artboard", fresh.0)), "{e}");
let v = s.execute("dataset.select", &json!({"name": "B"})).unwrap();
assert_eq!((v["applied"].as_u64(), v["skipped"].as_u64()), (Some(1), Some(2)), "{v}");
assert_eq!(plain(&s, t), "cat", "the text on the locked artboard was left alone");
assert!(s.doc().unwrap().doc.node(t).unwrap().visible, "and still shows");
assert!(!s.doc().unwrap().doc.node(r).unwrap().visible, "the rectangle off it applied");
// Update Data Set keeps the row's values for the art it can't read.
let v = s.execute("dataset.update", &json!({})).unwrap();
assert_eq!(v["values"], 1, "{v}");
let row = s.doc().unwrap().doc.variables.dataset("B").unwrap().values.clone();
assert_eq!(row.get("Name"), Some(&vectorcraft_doc::DataValue::Text("Bob".into())));
assert_eq!(row.get("Show"), Some(&vectorcraft_doc::DataValue::Visible(false)));
s.execute("artboard.setProps", &json!({"index": 1, "locked": false})).unwrap();
let v = s.execute("dataset.select", &json!({"name": "B"})).unwrap();
assert_eq!((v["applied"].as_u64(), v["skipped"].as_u64()), (Some(3), Some(0)), "{v}");
assert_eq!(plain(&s, t), "Bob");
}
/// A locked artboard elsewhere in the document does not stop threaded type on an unlocked artboard
/// from having its whole story rewritten, and type on the locked artboard is still left alone.
#[test]
fn threaded_type_on_an_unlocked_artboard_is_rewritten_beside_a_locked_artboard() {
let (mut s, a, b, story) = threaded(200);
let far = NodeId(s.execute("text.create", &json!({"x": 2050, "y": 50, "text": "cat"})).unwrap()["id"].as_u64().unwrap());
s.execute("artboard.new", &json!({"x": 2000, "y": 0, "width": 400, "height": 400})).unwrap();
s.execute("variable.define", &json!({"name": "Name", "kind": "text"})).unwrap();
s.execute("variable.define", &json!({"name": "Tail", "kind": "text"})).unwrap();
s.execute("variable.bind", &json!({"variable": "Name", "ids": [a.0]})).unwrap();
s.execute("variable.bind", &json!({"variable": "Tail", "ids": [far.0]})).unwrap();
s.execute("dataset.new", &json!({"name": "B", "values": {"Name": "Bob", "Tail": "dog"}})).unwrap();
s.execute("select.none", &json!({})).unwrap();
s.execute("artboard.setProps", &json!({"index": 1, "locked": true})).unwrap();
let v = s.execute("dataset.select", &json!({"name": "B"})).unwrap();
assert_eq!((v["applied"].as_u64(), v["skipped"].as_u64()), (Some(1), Some(1)), "{v}");
assert_eq!((plain(&s, a), plain(&s, b)), ("Bob".to_string(), String::new()), "the whole story was rewritten");
assert_eq!(plain(&s, far), "cat", "the text on the locked artboard was left alone");
assert!(!story.is_empty());
}
/// Binding fails for locked art and for art in a hidden or locked group or layer, and the
/// error names which of the three applies.
#[test]
+1
View File
@@ -5275,6 +5275,7 @@ digits Malayalam Malaiàlam
@msg no user library folder here aquí no hi ha cap carpeta de biblioteca d’usuari
@msg no user workspace `{from}` no hi ha l’espai de treball d’usuari `{from}`
@msg node {_1} is not text el node {_1} no és text
@msg node {_1} is on a locked artboard el node {_1} és en un tauler bloquejat
@msg Non-finite dimension Cota no finita
@msg not a blend no és una fusió
@msg not a DXF drawing no és un dibuix DXF
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -4609,6 +4609,7 @@ imageTrace Outline Obrys
@msg no user library folder here zde není složka uživatelských knihoven
@msg no user workspace `{from}` uživatelský pracovní prostor `{from}` neexistuje
@msg node {_1} is not text uzel {_1} není text
@msg node {_1} is on a locked artboard uzel {_1} je na zamčené pracovní ploše
@msg not a DXF drawing nejde o výkres DXF
@msg not a VectorCraft file: {0} nejde o soubor VectorCraft: {0}
@msg not a VectorCraft shortcut set (missing `overrides`) nejde o sadu klávesových zkratek VectorCraft (chybí `overrides`)
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -4218,6 +4218,7 @@ theme Appearance Erscheinungsbild
@msg no user library folder here hier gibt es keinen Ordner für Benutzerbibliotheken
@msg no user workspace `{from}` kein Benutzerarbeitsbereich `{from}`
@msg node {_1} is not text Knoten {_1} ist kein Text
@msg node {_1} is on a locked artboard Knoten {_1} liegt auf einer gesperrten Zeichenfläche
@msg not a DXF drawing keine DXF-Zeichnung
@msg not a VectorCraft file: {0} keine VectorCraft-Datei: {0}
@msg not a VectorCraft shortcut set (missing `overrides`) kein VectorCraft-Tastaturbefehlssatz (`overrides` fehlt)
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -4257,6 +4257,7 @@ digits Malayalam Μαλαγιάλαμ
@msg no user library folder here δεν υπάρχει φάκελος βιβλιοθήκης χρήστη εδώ
@msg no user workspace `{from}` δεν υπάρχει χώρος εργασίας χρήστη `{from}`
@msg node {_1} is not text ο κόμβος {_1} δεν είναι κείμενο
@msg node {_1} is on a locked artboard ο κόμβος {_1} βρίσκεται σε κλειδωμένο πίνακα σχεδίασης
@msg not a DXF drawing δεν είναι σχέδιο DXF
@msg not a VectorCraft file: {0} δεν είναι αρχείο VectorCraft: {0}
@msg not a VectorCraft shortcut set (missing `overrides`) δεν είναι σύνολο συντομεύσεων VectorCraft (λείπει το `overrides`)
Can't render this file because it contains an unexpected character in line 163 and column 5.
+1
View File
@@ -4302,6 +4302,7 @@ axis Both Ambos
@msg no user library folder here aquí no hay ninguna carpeta de bibliotecas de usuario
@msg no user workspace `{from}` no existe el espacio de trabajo de usuario `{from}`
@msg node {_1} is not text el nodo {_1} no es texto
@msg node {_1} is on a locked artboard el nodo {_1} está en una mesa de trabajo bloqueada
@msg not a DXF drawing no es un dibujo DXF
@msg not a VectorCraft file: {0} no es un archivo de VectorCraft: {0}
@msg not a VectorCraft shortcut set (missing `overrides`) no es un conjunto de atajos de VectorCraft (falta `overrides`)
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -4517,6 +4517,7 @@ imageTrace Outline Ääriviiva
@msg no user library folder here täällä ei ole käyttäjäkirjastokansiota
@msg no user workspace `{from}` ei käyttäjän työtilaa `{from}`
@msg node {_1} is not text solmu {_1} ei ole tekstiä
@msg node {_1} is on a locked artboard solmu {_1} on lukitulla piirtoalustalla
@msg not a DXF drawing ei DXF-piirustus
@msg not a VectorCraft file: {0} ei VectorCraft-tiedosto: {0}
@msg not a VectorCraft shortcut set (missing `overrides`) ei VectorCraftin pikanäppäinjoukko (`overrides` puuttuu)
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -4292,6 +4292,7 @@ axis Both Les deux
@msg no user library folder here aucun dossier de bibliothèques utilisateur ici
@msg no user workspace `{from}` aucun espace de travail utilisateur `{from}`
@msg node {_1} is not text le nœud {_1} n’est pas du texte
@msg node {_1} is on a locked artboard le nœud {_1} est sur un plan de travail verrouillé
@msg not a DXF drawing ce n’est pas un dessin DXF
@msg not a VectorCraft file: {0} ce n’est pas un fichier VectorCraft : {0}
@msg not a VectorCraft shortcut set (missing `overrides`) ce n’est pas un jeu de raccourcis VectorCraft (`overrides` manquant)
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -4976,6 +4976,7 @@ imageTrace Outline Körvonal
@msg no user library folder here itt nincs felhasználói könyvtármappa
@msg no user workspace `{from}` nincs ilyen felhasználói munkaterület: `{from}`
@msg node {_1} is not text a csomópont nem szöveg: {_1}
@msg node {_1} is on a locked artboard a csomópont zárolt rajztáblán van: {_1}
@msg not a DXF drawing nem DXF-rajz
@msg not a file nem fájl
@msg not a font file nem betűtípusfájl
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -4344,6 +4344,7 @@ axis Both Entrambi
@msg no user library folder here nessuna cartella di librerie utente qui
@msg no user workspace `{from}` nessuna area di lavoro utente `{from}`
@msg node {_1} is not text il nodo {_1} non è testo
@msg node {_1} is on a locked artboard il nodo {_1} è su una tavola da disegno bloccata
@msg not a DXF drawing non è un disegno DXF
@msg not a VectorCraft file: {0} non è un file VectorCraft: {0}
@msg not a VectorCraft shortcut set (missing `overrides`) non è un set di scelte rapide VectorCraft (manca `overrides`)
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -4306,6 +4306,7 @@ swatch Bright Violet ビビッドバイオレット
@msg a key object sits on that point そのポイントにはキーオブジェクトがあります
@msg no graphic style `{name}` グラフィックスタイル `{name}` が見つかりません
@msg node {_1} is not text ノード {_1} はテキストではありません
@msg node {_1} is on a locked artboard ノード {_1} はロックされたアートボード上にあります
@msg Text Wrap: select a wrap object テキストの回り込み: 回り込みオブジェクトを選択してください
@msg layers can't be wrap objects レイヤーは回り込みオブジェクトにできません
@msg line {line}: value for `{var}` must be true or false {line} 行目: `{var}` の値には true または false を指定してください
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -4059,6 +4059,7 @@ font-technology Variable ცვლადი
@msg no user library folder here აქ მომხმარებლის ბიბლიოთეკის საქაღალდე არ არის
@msg no user workspace `{from}` მომხმარებლის სამუშაო სივრცე `{from}` არ არის
@msg node {_1} is not text კვანძი {_1} ტექსტი არ არის
@msg node {_1} is on a locked artboard კვანძი {_1} ჩაკეტილ სამუშაო დაფაზეა
@msg not a DXF drawing ეს არ არის DXF ნახაზი
@msg not a VectorCraft file: {0} ეს არ არის VectorCraft-ის ფაილი: {0}
@msg not a VectorCraft shortcut set (missing `overrides`) ეს არ არის VectorCraft-ის მალსახმობების ნაკრები (აკლია `overrides`)
Can't render this file because it is too large.
+1
View File
@@ -4233,6 +4233,7 @@ theme Appearance 외관
@msg a key object sits on that point 그 포인트에 키 개체가 있습니다
@msg no graphic style `{name}` `{name}` 그래픽 스타일이 없습니다
@msg node {_1} is not text 노드 {_1}은(는) 텍스트가 아닙니다
@msg node {_1} is on a locked artboard 노드 {_1}이(가) 잠긴 아트보드에 있습니다
@msg Text Wrap: select a wrap object 텍스트 감싸기: 감싸기 개체를 선택하세요
@msg layers can't be wrap objects 레이어는 감싸기 개체가 될 수 없습니다
@msg line {line}: value for `{var}` must be true or false {line}행: `{var}`의 값은 true 또는 false여야 합니다
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -4432,6 +4432,7 @@ imageTrace Outline Kontur
@msg no user library folder here brak folderu bibliotek użytkownika
@msg no user workspace `{from}` brak obszaru roboczego użytkownika `{from}`
@msg node {_1} is not text węzeł {_1} nie jest tekstem
@msg node {_1} is on a locked artboard węzeł {_1} jest na zablokowanym obszarze kompozycji
@msg not a DXF drawing to nie jest rysunek DXF
@msg not a VectorCraft file: {0} to nie jest plik VectorCraft: {0}
@msg not a VectorCraft shortcut set (missing `overrides`) to nie jest zestaw skrótów VectorCraft (brak `overrides`)
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -3887,6 +3887,7 @@ axis Both Ambos
@msg no user library folder here nenhuma pasta de biblioteca do usuário aqui
@msg no user workspace `{from}` nenhum espaço de trabalho do usuário `{from}`
@msg node {_1} is not text o nó {_1} não é texto
@msg node {_1} is on a locked artboard o nó {_1} está em uma prancheta bloqueada
@msg not a DXF drawing não é um desenho DXF
@msg not a VectorCraft file: {0} não é um arquivo do VectorCraft: {0}
@msg not a VectorCraft shortcut set (missing `overrides`) não é um conjunto de atalhos do VectorCraft (falta `overrides`)
Can't render this file because it contains an unexpected character in line 6 and column 47.
+1
View File
@@ -4339,6 +4339,7 @@ axis Both Оба
@msg no user library folder here здесь нет папки пользовательских библиотек
@msg no user workspace `{from}` нет пользовательской рабочей среды `{from}`
@msg node {_1} is not text узел {_1} не является текстом
@msg node {_1} is on a locked artboard узел {_1} находится на заблокированной монтажной области
@msg not a DXF drawing не является чертежом DXF
@msg not a VectorCraft file: {0} не является файлом VectorCraft: {0}
@msg not a VectorCraft shortcut set (missing `overrides`) не является набором сочетаний клавиш VectorCraft (отсутствует `overrides`)
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -4207,6 +4207,7 @@ axis Both Båda
@msg no user library folder here ingen mapp för användarbibliotek här
@msg no user workspace `{from}` ingen användararbetslayout `{from}`
@msg node {_1} is not text nod {_1} är inte text
@msg node {_1} is on a locked artboard nod {_1} ligger på en låst rityta
@msg not a DXF drawing inte en DXF-ritning
@msg not a VectorCraft file: {0} inte en VectorCraft-fil: {0}
@msg not a VectorCraft shortcut set (missing `overrides`) inte en kortkommandouppsättning för VectorCraft (`overrides` saknas)
Can't render this file because it contains an unexpected character in line 5 and column 25.
+1
View File
@@ -4062,6 +4062,7 @@ axis Both Her İkisi
@msg no user library folder here burada kullanıcı kitaplığı klasörü yok
@msg no user workspace `{from}` kullanıcı çalışma alanı yok `{from}`
@msg node {_1} is not text {_1} düğümü metin değil
@msg node {_1} is on a locked artboard {_1} düğümü kilitli bir çalışma yüzeyinde
@msg not a DXF drawing DXF çizimi değil
@msg not a VectorCraft file: {0} bir VectorCraft dosyası değil: {0}
@msg not a VectorCraft shortcut set (missing `overrides`) VectorCraft kısayol seti değil ("geçersiz kılmalar" eksik)
Can't render this file because it contains an unexpected character in line 5 and column 25.
+1
View File
@@ -4328,6 +4328,7 @@ axis Both Обидві
@msg no user library folder here тут немає папки користувацьких бібліотек
@msg no user workspace `{from}` немає користувача робочого середовища `{from}`
@msg node {_1} is not text вузол {_1} не є текстом
@msg node {_1} is on a locked artboard вузол {_1} розташований на заблокованій монтажній області
@msg not a DXF drawing не є кресленням DXF
@msg not a VectorCraft file: {0} не є файлом VectorCraft: {0}
@msg not a VectorCraft shortcut set (missing `overrides`) не є набором поєднань клавіш VectorCraft (відсутнє `overrides`)
Can't render this file because it contains an unexpected character in line 177 and column 5.
+1
View File
@@ -4628,6 +4628,7 @@ theme Appearance Giao diện
@msg no user library folder here không có thư mục thư viện người dùng ở đây
@msg no user workspace `{from}` không có không gian làm việc người dùng `{from}`
@msg node {_1} is not text nút {_1} không phải là văn bản
@msg node {_1} is on a locked artboard nút {_1} nằm trên bảng vẽ bị khóa
@msg not a blend không phải đối tượng hòa trộn
@msg not a DXF drawing không phải bản vẽ DXF
@msg not a file không phải tệp
Can't render this file because it contains an unexpected character in line 199 and column 5.
+1
View File
@@ -4031,6 +4031,7 @@ imageTrace Outline 轮廓
@msg a graphic style named `{to}` already exists 名为 `{to}` 的图形样式已存在
@msg no graphic style `{name}` 没有图形样式 `{name}`
@msg node {_1} is not text 节点 {_1} 不是文字
@msg node {_1} is on a locked artboard 节点 {_1} 位于已锁定的画板上
@msg Text Wrap: select a wrap object 文本绕排:请选择一个绕排对象
@msg layers can't be wrap objects 图层不能作为绕排对象
@msg line {line}: value for `{var}` must be true or false 第 {line} 行:`{var}` 的值必须是 true 或 false
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -1938,6 +1938,7 @@ file-filter Templates 範本
@msg a graphic style named `{to}` already exists 名為 `{to}` 的繪圖樣式已存在
@msg no graphic style `{name}` 沒有繪圖樣式 `{name}`
@msg node {_1} is not text 節點 {_1} 不是文字
@msg node {_1} is on a locked artboard 節點 {_1} 位於已鎖定的工作區域上
@msg Text Wrap: select a wrap object 文字繞圖:請選取繞圖物件
@msg layers can't be wrap objects 圖層不能作為繞圖物件
@msg line {line}: value for `{var}` must be true or false 第 {line} 行:`{var}` 的值必須是 true 或 false
Can't render this file because it contains an unexpected character in line 6 and column 47.