From 613dcf3d7dbfb4bc27f0c5b95ecc254aed41a0a1 Mon Sep 17 00:00:00 2001 From: King of the all Cookies Date: Thu, 30 Jan 2025 21:49:59 +0300 Subject: [PATCH 1/4] Update translations.json --- translations.json | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/translations.json b/translations.json index 61b1564..352b181 100644 --- a/translations.json +++ b/translations.json @@ -174,6 +174,13 @@ "ja": "まず画像を開いてください", "uk": "Спочатку відкрийте зображення" }, + "open_file_first": { + "en": "Open a file first", + "ru": "Сначала откройте файл", + "eo": "Unue malfermu dosieron", + "ja": "まずファイルを開いてください", + "uk": "Спочатку відкрийте файл" + }, "pixel_table": { "en": "Pixel Table", "ru": "Таблица пикселей", @@ -229,5 +236,19 @@ "eo": "Okazis eraro dum la importado de la bildo", "ja": "画像のインポート中にエラーが発生しました", "uk": "Сталася помилка під час імпорту зображення" + }, + "show_kanji_button": { + "en": "Show Kanji", + "ru": "Показать кандзи", + "eo": "Montri Kandzi", + "ja": "漢字を表示", + "uk": "Показати кандзі" + }, + "enter_hex_code": { + "en": "Enter the hex code of the character:", + "ru": "Введите hex-код символа:", + "eo": "Enigu la heksan kodon de la signo:", + "ja": "文字の16進コードを入力してください:", + "uk": "Введіть hex-код символу:" } } From b542929c0453f8897f76b55524cefa1e7b397e0e Mon Sep 17 00:00:00 2001 From: King of the all Cookies Date: Sat, 1 Feb 2025 18:26:27 +0300 Subject: [PATCH 2/4] Update gui --- main.py | 179 +++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 124 insertions(+), 55 deletions(-) diff --git a/main.py b/main.py index 32b4d87..9b81aa9 100644 --- a/main.py +++ b/main.py @@ -1,8 +1,9 @@ -import tkinter as tk +import customtkinter as ctk from tkinter import filedialog, messagebox, simpledialog, ttk from PIL import Image, ImageTk import numpy as np import json +import os # Load translations from JSON file with open('translations.json', 'r', encoding='utf-8') as f: @@ -30,7 +31,7 @@ def open_file(): global file_path, image, tk_image, zoom_level file_path = filedialog.askopenfilename(title=translations["open_file"][language.get()], filetypes=[("All Files", "*.*")]) if file_path: - file_label.config(text=f"{translations['selected_file'][language.get()]} {file_path.split('/')[-1]}") + file_label.configure(text=f"{translations['selected_file'][language.get()]} {file_path.split('/')[-1]}") try: # Проверка расширения if not file_path.lower().endswith('.bin'): @@ -44,7 +45,7 @@ def open_file(): except Exception as e: messagebox.showerror(translations["error"][language.get()], f"{translations['file_processing_error'][language.get()]}: {e}") else: - file_label.config(text=translations["no_file_selected"][language.get()]) + file_label.configure(text=translations["no_file_selected"][language.get()]) def reload_image(): global image, tk_image @@ -61,8 +62,8 @@ def display_image(): if image: zoomed_image = image.resize((int(image.width * zoom_level), int(image.height * zoom_level)), Image.NEAREST) tk_image = ImageTk.PhotoImage(zoomed_image) - canvas.config(scrollregion=(0, 0, zoomed_image.width, zoomed_image.height)) - canvas.create_image(0, 0, anchor=tk.NW, image=tk_image) + canvas.configure(scrollregion=(0, 0, zoomed_image.width, zoomed_image.height)) + canvas.create_image(0, 0, anchor=ctk.NW, image=tk_image) # Clear existing grid lines canvas.delete("grid_line") @@ -133,11 +134,11 @@ def open_table_window(): messagebox.showerror(translations["error"][language.get()], translations["open_image_first"][language.get()]) return - table_window = tk.Toplevel(root) + table_window = ctk.CTkToplevel(root) table_window.title(translations["pixel_table"][language.get()]) - table_frame = tk.Frame(table_window) - table_frame.pack(fill=tk.BOTH, expand=True) + table_frame = ctk.CTkFrame(table_window) + table_frame.pack(fill=ctk.BOTH, expand=True) columns = simpledialog.askinteger(translations["table_settings"][language.get()], translations["enter_columns"][language.get()], initialvalue=16) if not columns: @@ -148,13 +149,13 @@ def open_table_window(): tree.heading(f"col{i}", text=f"{translations['column'][language.get()]} {i+1}") tree.column(f"col{i}", width=50, anchor='center') - scrollbar_y = ttk.Scrollbar(table_frame, orient=tk.VERTICAL, command=tree.yview) - scrollbar_x = ttk.Scrollbar(table_frame, orient=tk.HORIZONTAL, command=tree.xview) + scrollbar_y = ttk.Scrollbar(table_frame, orient=ctk.VERTICAL, command=tree.yview) + scrollbar_x = ttk.Scrollbar(table_frame, orient=ctk.HORIZONTAL, command=tree.xview) tree.configure(yscrollcommand=scrollbar_y.set, xscrollcommand=scrollbar_x.set) - scrollbar_y.pack(side=tk.RIGHT, fill=tk.Y) - scrollbar_x.pack(side=tk.BOTTOM, fill=tk.X) - tree.pack(fill=tk.BOTH, expand=True) + scrollbar_y.pack(side=ctk.RIGHT, fill=ctk.Y) + scrollbar_x.pack(side=ctk.BOTTOM, fill=ctk.X) + tree.pack(fill=ctk.BOTH, expand=True) pixels = np.array(image.convert('L')) rows = pixels.shape[0] @@ -167,7 +168,7 @@ def open_table_window(): values.append(pixels[row, col]) else: values.append('') - tree.insert('', tk.END, values=values) + tree.insert('', ctk.END, values=values) def export_image(): if not image: @@ -224,20 +225,85 @@ def update_language(*args): root.title(translations["title"][language_code]) notebook.tab(editor_tab, text=translations["editor_tab"][language_code]) notebook.tab(settings_tab, text=translations["settings_tab"][language_code]) - file_label.config(text=translations["no_file_selected"][language_code]) - open_button.config(text=translations["open_file_button"][language_code]) - width_label.config(text=translations["width_label"][language_code]) - table_button.config(text=translations["open_table_button"][language_code]) - save_button.config(text=translations["save_image_button"][language_code]) - save_bin_button.config(text=translations["save_bin_button"][language_code]) - reload_button.config(text=translations["reload_image_button"][language_code]) - redraw_grid_button.config(text=translations["redraw_grid_button"][language_code]) - export_button.config(text=translations["export_image_button"][language_code]) - import_button.config(text=translations["import_image_button"][language_code]) - language_label.config(text=translations["language_label"][language_code]) - grid_color_label.config(text=translations["grid_color_label"][language_code]) + file_label.configure(text=translations["no_file_selected"][language_code]) + open_button.configure(text=translations["open_file_button"][language_code]) + width_label.configure(text=translations["width_label"][language_code]) + table_button.configure(text=translations["open_table_button"][language_code]) + save_button.configure(text=translations["save_image_button"][language_code]) + save_bin_button.configure(text=translations["save_bin_button"][language.get()]) + reload_button.configure(text=translations["reload_image_button"][language_code]) + redraw_grid_button.configure(text=translations["redraw_grid_button"][language_code]) + export_button.configure(text=translations["export_image_button"][language_code]) + import_button.configure(text=translations["import_image_button"][language.get()]) + language_label.configure(text=translations["language_label"][language_code]) + grid_color_label.configure(text=translations["grid_color_label"][language_code]) + show_kanji_button.configure(text=translations["show_kanji_button"][language_code]) -root = tk.Tk() +def fromhex(a): + hex_from_str = {'0':'0000', '1':'0001', '2':'0010', '3':'0011', + '4':'0100', '5':'0101', '6':'0110', '7':'0111', '8':'1000', + '9':'1001', 'A':'1010', 'B':'1011', 'C':'1100', 'D':'1101', + 'E':'1110', 'F':'1111',} + b = '' + for char in a: + b += hex_from_str[char] + return int(b, 2) + +def show(kanji, file_path): + RESIZE = 5 + name = kanji + if kanji > 0x8000: + kanji -= 0x8000 + else: + messagebox.showerror(translations["error"][language.get()], translations["enter_hex_code"][language.get()]) + return + with open(file_path, 'rb') as f: + f = f.read() + offset = kanji * 32 + tile = f[offset:offset + 32] + picture = Image.new('1', (16, 16)) + x = 0 + y = 0 + for i in range(0, 32, 2): + bitmap = int.from_bytes(tile[i:i + 2]) + bitmap = bin(bitmap)[2:].zfill(16) + for number in bitmap: + if number == '1': + picture.putpixel((x, y), 1) + x += 1 + else: + x += 1 + y += 1 + x = 0 + picture = picture.resize((16 * RESIZE, 16 * RESIZE)) + picture.show(title=name) + +def open_kanji_window(): + if not file_path: + messagebox.showerror(translations["error"][language.get()], translations["open_file_first"][language.get()]) + return + + kanji_window = ctk.CTkToplevel(root) + kanji_window.title(translations["show_kanji_button"][language.get()]) + + kanji_label = ctk.CTkLabel(kanji_window, text=translations["enter_hex_code"][language.get()]) + kanji_label.pack(pady=5) + + kanji_entry = ctk.CTkEntry(kanji_window) + kanji_entry.pack(pady=5) + + def show_kanji(): + kanji_hex = kanji_entry.get() + try: + kanji = fromhex(kanji_hex) + show(kanji, file_path) + except Exception as e: + messagebox.showerror(translations["error"][language.get()], f"{translations['file_processing_error'][language.get()]}: {e}") + + show_button = ctk.CTkButton(kanji_window, text=translations["show_kanji_button"][language.get()], command=show_kanji) + show_button.pack(pady=5) + +root = ctk.CTk() root.title(translations["title"]["en"]) file_path = "" @@ -248,7 +314,7 @@ drawing = False new_color = None # Language selection -language = tk.StringVar(value="en") +language = ctk.StringVar(value="en") language_options = ["en", "ru", "eo", "ja", "uk"] # Notebook for tabs @@ -259,57 +325,60 @@ notebook.pack(expand=True, fill="both") editor_tab = ttk.Frame(notebook) notebook.add(editor_tab, text=translations["editor_tab"]["en"]) -file_label = tk.Label(editor_tab, text=translations["no_file_selected"]["en"]) +file_label = ctk.CTkLabel(editor_tab, text=translations["no_file_selected"]["en"]) file_label.pack(pady=5) -open_button = tk.Button(editor_tab, text=translations["open_file_button"]["en"], command=open_file) +open_button = ctk.CTkButton(editor_tab, text=translations["open_file_button"]["en"], command=open_file) open_button.pack(pady=5) -width_label = tk.Label(editor_tab, text=translations["width_label"]["en"]) +width_label = ctk.CTkLabel(editor_tab, text=translations["width_label"]["en"]) width_label.pack(pady=5) -width_entry = tk.Entry(editor_tab) +width_entry = ctk.CTkEntry(editor_tab) width_entry.insert(0, "128") width_entry.pack(pady=5) -table_button = tk.Button(editor_tab, text=translations["open_table_button"]["en"], command=open_table_window) +table_button = ctk.CTkButton(editor_tab, text=translations["open_table_button"]["en"], command=open_table_window) table_button.pack(pady=5) -save_button = tk.Button(editor_tab, text=translations["save_image_button"]["en"], command=save_image) +save_button = ctk.CTkButton(editor_tab, text=translations["save_image_button"]["en"], command=save_image) save_button.pack(pady=5) -save_bin_button = tk.Button(editor_tab, text=translations["save_bin_button"]["en"], command=save_to_bin) +save_bin_button = ctk.CTkButton(editor_tab, text=translations["save_bin_button"]["en"], command=save_to_bin) save_bin_button.pack(pady=5) -reload_button = tk.Button(editor_tab, text=translations["reload_image_button"]["en"], command=reload_image) +reload_button = ctk.CTkButton(editor_tab, text=translations["reload_image_button"]["en"], command=reload_image) reload_button.pack(pady=5) -redraw_grid_button = tk.Button(editor_tab, text=translations["redraw_grid_button"]["en"], command=redraw_grid) +redraw_grid_button = ctk.CTkButton(editor_tab, text=translations["redraw_grid_button"]["en"], command=redraw_grid) redraw_grid_button.pack(pady=5) -export_button = tk.Button(editor_tab, text=translations["export_image_button"]["en"], command=export_image) +export_button = ctk.CTkButton(editor_tab, text=translations["export_image_button"]["en"], command=export_image) export_button.pack(pady=5) -import_button = tk.Button(editor_tab, text=translations["import_image_button"]["en"], command=import_image) +import_button = ctk.CTkButton(editor_tab, text=translations["import_image_button"]["en"], command=import_image) import_button.pack(pady=5) -canvas_frame = tk.Frame(editor_tab) -canvas_frame.pack(fill=tk.BOTH, expand=True) +show_kanji_button = ctk.CTkButton(editor_tab, text=translations["show_kanji_button"]["en"], command=open_kanji_window) +show_kanji_button.pack(pady=5) -canvas = tk.Canvas(canvas_frame, bg="white") -canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=True) +canvas_frame = ctk.CTkFrame(editor_tab) +canvas_frame.pack(fill=ctk.BOTH, expand=True) -scrollbar_y = tk.Scrollbar(canvas_frame, orient=tk.VERTICAL, command=canvas.yview) -scrollbar_y.pack(side=tk.RIGHT, fill=tk.Y) -canvas.config(yscrollcommand=scrollbar_y.set) +canvas = ctk.CTkCanvas(canvas_frame, bg="white") +canvas.pack(side=ctk.LEFT, fill=ctk.BOTH, expand=True) -scrollbar_x = tk.Scrollbar(editor_tab, orient=tk.HORIZONTAL, command=canvas.xview) -scrollbar_x.pack(side=tk.BOTTOM, fill=tk.X) -canvas.config(xscrollcommand=scrollbar_x.set) +scrollbar_y = ctk.CTkScrollbar(canvas_frame, orientation="vertical", command=canvas.yview) +scrollbar_y.pack(side=ctk.RIGHT, fill=ctk.Y) +canvas.configure(yscrollcommand=scrollbar_y.set) -zoom_scale = tk.Scale(editor_tab, from_=100, to=500, orient=tk.HORIZONTAL, label="Zoom Level (%)", command=update_zoom_level) +scrollbar_x = ctk.CTkScrollbar(editor_tab, orientation="horizontal", command=canvas.xview) +scrollbar_x.pack(side=ctk.BOTTOM, fill=ctk.X) +canvas.configure(xscrollcommand=scrollbar_x.set) + +zoom_scale = ctk.CTkSlider(editor_tab, from_=100, to=500, orientation="horizontal", command=update_zoom_level) zoom_scale.set(100) -zoom_scale.pack(side=tk.BOTTOM, fill=tk.X) +zoom_scale.pack(side=ctk.BOTTOM, fill=ctk.X) canvas.bind("", start_drawing) canvas.bind("", draw) @@ -323,16 +392,16 @@ root.bind('', bind_hot_reload) settings_tab = ttk.Frame(notebook) notebook.add(settings_tab, text=translations["settings_tab"]["en"]) -language_label = tk.Label(settings_tab, text=translations["language_label"]["en"]) +language_label = ctk.CTkLabel(settings_tab, text=translations["language_label"]["en"]) language_label.pack(pady=5) -language_menu = tk.OptionMenu(settings_tab, language, *language_options, command=update_language) +language_menu = ctk.CTkOptionMenu(settings_tab, variable=language, values=language_options, command=update_language) language_menu.pack(pady=5) -grid_color_label = tk.Label(settings_tab, text=translations["grid_color_label"]["en"]) +grid_color_label = ctk.CTkLabel(settings_tab, text=translations["grid_color_label"]["en"]) grid_color_label.pack(pady=5) -grid_color_entry = tk.Entry(settings_tab) +grid_color_entry = ctk.CTkEntry(settings_tab) grid_color_entry.insert(0, "255,0,0") grid_color_entry.pack(pady=5) From 81a7e375ffa825d97dc77bba07ca62488d046555 Mon Sep 17 00:00:00 2001 From: King of the all Cookies Date: Sun, 30 Mar 2025 22:41:40 +0300 Subject: [PATCH 3/4] =?UTF-8?q?=E3=83=95=E3=82=A9=E3=83=AB=E3=83=80?= =?UTF-8?q?=E3=81=B8=E3=81=AE=E3=83=93=E3=83=83=E3=83=88=E3=83=9E=E3=83=83?= =?UTF-8?q?=E3=83=97=E3=82=A8=E3=82=AF=E3=82=B9=E3=83=9D=E3=83=BC=E3=83=88?= =?UTF-8?q?=E3=81=A8=E3=83=95=E3=82=A9=E3=83=AB=E3=83=80=E3=81=8B=E3=82=89?= =?UTF-8?q?=E3=81=AE=E3=83=93=E3=83=83=E3=83=88=E3=83=9E=E3=83=83=E3=83=97?= =?UTF-8?q?=E3=82=A4=E3=83=B3=E3=83=9D=E3=83=BC=E3=83=88=E3=82=92=E8=BF=BD?= =?UTF-8?q?=E5=8A=A0=E3=81=97=E3=81=BE=E3=81=97=E3=81=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.py | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) diff --git a/main.py b/main.py index 9b81aa9..e211abe 100644 --- a/main.py +++ b/main.py @@ -220,6 +220,112 @@ def update_zoom_level(value): def bind_hot_reload(event): reload_image() +def export_to_folder(): + if not image: + messagebox.showerror(translations["error"][language.get()], translations["open_image_first"][language.get()]) + return + + folder_path = filedialog.askdirectory(title=translations["select_folder"][language.get()]) + if not folder_path: + return + + try: + width = int(width_entry.get()) + cell_size = width + img_width, img_height = image.size + + # Create info file + with open(os.path.join(folder_path, 'info.txt'), 'w') as f: + f.write(str(width)) + + # Calculate grid dimensions + cols = img_width // cell_size + rows = img_height // cell_size + + # Save each cell + for row in range(rows): + for col in range(cols): + left = col * cell_size + upper = row * cell_size + right = left + cell_size + lower = upper + cell_size + + cell = image.crop((left, upper, right, lower)) + cell.save(os.path.join(folder_path, f"{row}_{col}.tiff")) + + messagebox.showinfo(translations["success"][language.get()], translations["image_exported"][language.get()]) + except Exception as e: + messagebox.showerror(translations["error"][language.get()], f"Export error: {str(e)}") + +def import_from_folder(): + global image, zoom_level + folder_path = filedialog.askdirectory(title=translations["select_folder"][language.get()]) + if not folder_path: + return + + try: + # Read width info + with open(os.path.join(folder_path, 'info.txt'), 'r') as f: + saved_width = int(f.read().strip()) + + current_width = int(width_entry.get()) + if saved_width != current_width: + messagebox.showerror( + translations["error"][language.get()], + translations["width_mismatch_error"][language.get()].format( + expected=current_width, actual=saved_width + ) + ) + return + + # Collect and sort cell files + cell_files = [] + for fname in os.listdir(folder_path): + if fname.endswith('.tiff'): + try: + parts = fname.split('_') + row = int(parts[0]) + col = int(parts[1].split('.')[0]) + cell_files.append((row, col, fname)) + except: + messagebox.showerror( + translations["error"][language.get()], + translations["invalid_filename_error"][language.get()].format(filename=fname)) + return + + if not cell_files: + messagebox.showerror(translations["error"][language.get()], translations["no_cell_files"][language.get()]) + return + + # Sort files by row and column + cell_files.sort() + max_row = max(r for r, c, _ in cell_files) + max_col = max(c for r, c, _ in cell_files) + + # Create empty image + cell_size = current_width + full_width = (max_col + 1) * cell_size + full_height = (max_row + 1) * cell_size + new_image = Image.new('L', (full_width, full_height)) + + # Paste cells + for row, col, fname in cell_files: + cell_path = os.path.join(folder_path, fname) + cell = Image.open(cell_path).convert('L') + x = col * cell_size + y = row * cell_size + new_image.paste(cell, (x, y)) + + image = new_image + zoom_level = 1.0 + display_image() + messagebox.showinfo( + translations["success"][language.get()], + translations["image_imported"][language.get()] +) + except Exception as e: + messagebox.showerror(translations["error"][language.get()], f"Import error: {str(e)}") + def update_language(*args): language_code = language.get() root.title(translations["title"][language_code]) @@ -238,6 +344,8 @@ def update_language(*args): language_label.configure(text=translations["language_label"][language_code]) grid_color_label.configure(text=translations["grid_color_label"][language_code]) show_kanji_button.configure(text=translations["show_kanji_button"][language_code]) + export_folder_button.configure(text=translations["export_folder_button"][language.get()]) + import_folder_button.configure(text=translations["import_folder_button"][language.get()]) def fromhex(a): hex_from_str = {'0':'0000', '1':'0001', '2':'0010', '3':'0011', @@ -361,7 +469,11 @@ import_button.pack(pady=5) show_kanji_button = ctk.CTkButton(editor_tab, text=translations["show_kanji_button"]["en"], command=open_kanji_window) show_kanji_button.pack(pady=5) +export_folder_button = ctk.CTkButton(editor_tab, text=translations["export_folder_button"][language.get()], command=export_to_folder) +export_folder_button.pack(pady=5) +import_folder_button = ctk.CTkButton(editor_tab, text=translations["import_folder_button"][language.get()], command=import_from_folder) +import_folder_button.pack(pady=5) canvas_frame = ctk.CTkFrame(editor_tab) canvas_frame.pack(fill=ctk.BOTH, expand=True) From 6edf1a61880634643e393ba7d26c26628f352fde Mon Sep 17 00:00:00 2001 From: King of the all Cookies Date: Sun, 30 Mar 2025 22:42:24 +0300 Subject: [PATCH 4/4] =?UTF-8?q?=E5=BF=85=E8=A6=81=E3=81=AA=E8=BB=A2?= =?UTF-8?q?=E9=80=81=E3=81=8C=E8=BF=BD=E5=8A=A0=E3=81=95=E3=82=8C=E3=81=BE?= =?UTF-8?q?=E3=81=97=E3=81=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- translations.json | 51 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/translations.json b/translations.json index 352b181..2d66ec3 100644 --- a/translations.json +++ b/translations.json @@ -250,5 +250,54 @@ "eo": "Enigu la heksan kodon de la signo:", "ja": "文字の16進コードを入力してください:", "uk": "Введіть hex-код символу:" - } + }, + "export_folder_button": { + "en": "Export as Folder", + "ru": "Экспортировать как папку", + "eo": "Eksporti kiel Dosierujo", + "ja": "フォルダとしてエクスポート", + "uk": "Експортувати як папку" + }, + "import_folder_button": { + "en": "Import from Folder", + "ru": "Импортировать из папки", + "eo": "Importi el Dosierujo", + "ja": "フォルダからインポート", + "uk": "Імпортувати з папки" + }, + "width_mismatch_error": { + "en": "Width mismatch! Expected: {expected}, Actual: {actual}", + "ru": "Несоответствие ширины! Ожидалось: {expected}, Фактическая: {actual}", + "eo": "Larĝo-neakordo! Atendita: {expected}, Reala: {actual}", + "ja": "幅が一致しません! 期待: {expected}, 実際: {actual}", + "uk": "Невідповідність ширини! Очікувано: {expected}, Фактична: {actual}" + }, + "invalid_filename_error": { + "en": "Invalid filename format: {filename}", + "ru": "Недопустимый формат имени файла: {filename}", + "eo": "Nevalida dosiernoma formato: {filename}", + "ja": "無効なファイル名形式: {filename}", + "uk": "Невірний формат імені файлу: {filename}" + }, + "select_folder": { + "en": "Select Folder", + "ru": "Выберите папку", + "eo": "Elektu Dosierujon", + "ja": "フォルダを選択", + "uk": "Виберіть папку" + }, + "image_imported": { + "en": "Image imported successfully!", + "ru": "Изображение успешно импортировано!", + "eo": "Bildo importita sukcese!", + "ja": "画像のインポートが成功しました!", + "uk": "Зображення успішно імпортовано!" + }, + "no_cell_files": { + "en": "No cell files found!", + "ru": "Файлы клеток не найдены!", + "eo": "Neniu ĉeldosieroj trovitaj!", + "ja": "セルファイルが見つかりません!", + "uk": "Файли клітинок не знайдено!" + } }