Compare commits

...

38 Commits

Author SHA1 Message Date
David Simpson
9a16cf9e02 change MonitorService providers to injectable deps 2022-05-20 17:53:34 +02:00
Francesco Stasi
a4ff05a82b monitor service provider singleton 2022-05-19 16:56:37 +02:00
Alberto Iannaccone
0427759fdb refactor monitor settings interfaces 2022-05-19 11:19:13 +02:00
Francesco Stasi
80ade4c37e updated pseudo code 2022-05-19 10:59:20 +02:00
Francesco Stasi
355dec8aaa monitor settings provider stub 2022-05-19 10:40:01 +02:00
Alberto Iannaccone
7bf4ea0637 add MonitorSettingsProvider interface 2022-05-17 17:45:47 +02:00
Alberto Iannaccone
1982609c87 fix upload when monitor is open 2022-05-12 15:28:13 +02:00
Alberto Iannaccone
62eaeb1c74 update arduino-cli to 0.22.0 2022-05-10 15:54:04 +02:00
Alberto Iannaccone
9b58c9d0c8 delete duplex when connection is closed 2022-05-10 15:53:48 +02:00
Alberto Iannaccone
eff960bb7f fix monitor connection 2022-05-09 14:56:52 +02:00
Mark Sujew
fbe8fb421a Fix MonitorManagerProxy DI issue 2022-05-09 14:56:52 +02:00
Silvano Cerza
a8d803e7c3 Add missing binding 2022-05-09 14:56:52 +02:00
Silvano Cerza
397ca5665f coreClientProvider is now set when constructing MonitorService 2022-05-09 14:56:52 +02:00
Silvano Cerza
f9da9fc24b Delete unnecessary Symbol 2022-05-09 14:56:52 +02:00
Silvano Cerza
b97af32bb8 Fix backend logger bindings 2022-05-09 14:56:52 +02:00
Silvano Cerza
ce2f1c227a Updated MonitorWidget to use new monitor proxy 2022-05-09 14:56:52 +02:00
Silvano Cerza
7889f40834 Changed MonitorWidget and children to use new monitor proxy 2022-05-09 14:56:52 +02:00
Silvano Cerza
6b7b33356d Changed plotter contribution to use new manager proxy 2022-05-09 14:56:52 +02:00
Silvano Cerza
ad781f0bfc Remove unused file 2022-05-09 14:56:52 +02:00
Silvano Cerza
6cf61c498a More serial classes removal 2022-05-09 14:56:52 +02:00
Silvano Cerza
50239c5756 Add generic monitor settings storaging 2022-05-09 14:56:52 +02:00
Silvano Cerza
cbd5b4de1b WebSocketProvider is not injectable anymore 2022-05-09 14:56:52 +02:00
Silvano Cerza
bf958fd8cf Proxied more monitor methods to frontend 2022-05-09 14:56:52 +02:00
Silvano Cerza
ee265aec90 Changed how connection is handled on upload 2022-05-09 14:56:52 +02:00
Silvano Cerza
9058abb015 Remove several unnecessary serial monitor classes 2022-05-09 14:56:52 +02:00
Silvano Cerza
31b704cdb9 Moved settings to MonitorService 2022-05-09 14:56:52 +02:00
Silvano Cerza
61b8bdeec9 Add monitor proxy functions for the frontend 2022-05-09 14:56:52 +02:00
Silvano Cerza
c5695d3a76 Fixed WebSocketChange event signature 2022-05-09 14:56:52 +02:00
Silvano Cerza
480492a7c8 Enhance MonitorManager APIs 2022-05-09 14:56:52 +02:00
Silvano Cerza
2c95e7f033 Changed upload settings 2022-05-09 14:56:52 +02:00
Silvano Cerza
116b3d5984 Moved some interfaces 2022-05-09 14:56:52 +02:00
Silvano Cerza
750796d3a0 Rename WebSocketService to WebSocketProvider and uninjected it 2022-05-09 14:56:52 +02:00
Silvano Cerza
3133b01c4a Implement MonitorService to handle pluggable monitor lifetime 2022-05-09 14:56:52 +02:00
Silvano Cerza
ebab0b226f Scaffold interfaces and classes for pluggable monitors 2022-05-09 14:56:52 +02:00
Francesco Stasi
2b2ea72643 backend structure WIP 2022-05-09 14:56:52 +02:00
per1234
289f9d7946 Allow flexibility in OS type selections in issue forms
GitHub issue forms are used in this repository to facilitate the creation of high quality issues. These provide input
fields for each of the distinct classes of information which will be essential for the evaluation of the issues.

One of these fields is for the user's operating system. A dropdown menu is used for the selection of the high level
operating system type. Previously this only permitted the selection of a single option. A devoted contributor might have
made the effort to determine that the issue applies to multiple operating system types only to be met with the inability
to provide this information via the dedicated field.

The field also did not offer an option to indicate that the operating system was irrelevant to the issue (e.g., a
subject related to the repository assets).

Those issues are resolved by the following changes:

- Configure the field to allow multiple selections
- Add a "N/A" option to the menu
2022-05-05 02:27:22 -07:00
github-actions[bot]
905b78008d Updated translation files (#968)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-04-29 15:44:04 +02:00
Mark Sujew
11961bb7c7 Save all open editors before running Save As (#939)
* Save all open editors before running `Save As`

* Only save unsaved changes to new sketch
2022-04-29 15:42:48 +02:00
53 changed files with 4270 additions and 2351 deletions

View File

@@ -37,11 +37,13 @@ body:
id: os id: os
attributes: attributes:
label: Operating system label: Operating system
description: Which operating system are you using on your computer? description: Which operating system(s) are you using on your computer?
multiple: true
options: options:
- Windows - Windows
- Linux - Linux
- macOS - macOS
- N/A
validations: validations:
required: true required: true
- type: input - type: input

View File

@@ -32,11 +32,13 @@ body:
id: os id: os
attributes: attributes:
label: Operating system label: Operating system
description: Which operating system are you using on your computer? description: Which operating system(s) are you using on your computer?
multiple: true
options: options:
- Windows - Windows
- Linux - Linux
- macOS - macOS
- N/A
validations: validations:
required: true required: true
- type: input - type: input

View File

@@ -157,7 +157,7 @@
], ],
"arduino": { "arduino": {
"cli": { "cli": {
"version": "0.21.0" "version": "0.22.0"
}, },
"fwuploader": { "fwuploader": {
"version": "2.0.0" "version": "2.0.0"

View File

@@ -69,20 +69,12 @@ import { ScmContribution } from './theia/scm/scm-contribution';
import { SearchInWorkspaceFrontendContribution as TheiaSearchInWorkspaceFrontendContribution } from '@theia/search-in-workspace/lib/browser/search-in-workspace-frontend-contribution'; import { SearchInWorkspaceFrontendContribution as TheiaSearchInWorkspaceFrontendContribution } from '@theia/search-in-workspace/lib/browser/search-in-workspace-frontend-contribution';
import { SearchInWorkspaceFrontendContribution } from './theia/search-in-workspace/search-in-workspace-frontend-contribution'; import { SearchInWorkspaceFrontendContribution } from './theia/search-in-workspace/search-in-workspace-frontend-contribution';
import { LibraryListWidgetFrontendContribution } from './library/library-widget-frontend-contribution'; import { LibraryListWidgetFrontendContribution } from './library/library-widget-frontend-contribution';
import { SerialServiceClientImpl } from './serial/serial-service-client-impl';
import {
SerialServicePath,
SerialService,
SerialServiceClient,
} from '../common/protocol/serial-service';
import { import {
ConfigService, ConfigService,
ConfigServicePath, ConfigServicePath,
} from '../common/protocol/config-service'; } from '../common/protocol/config-service';
import { MonitorWidget } from './serial/monitor/monitor-widget'; import { MonitorWidget } from './serial/monitor/monitor-widget';
import { MonitorViewContribution } from './serial/monitor/monitor-view-contribution'; import { MonitorViewContribution } from './serial/monitor/monitor-view-contribution';
import { SerialConnectionManager } from './serial/serial-connection-manager';
import { SerialModel } from './serial/serial-model';
import { TabBarDecoratorService as TheiaTabBarDecoratorService } from '@theia/core/lib/browser/shell/tab-bar-decorator'; import { TabBarDecoratorService as TheiaTabBarDecoratorService } from '@theia/core/lib/browser/shell/tab-bar-decorator';
import { TabBarDecoratorService } from './theia/core/tab-bar-decorator'; import { TabBarDecoratorService } from './theia/core/tab-bar-decorator';
import { ProblemManager as TheiaProblemManager } from '@theia/markers/lib/browser'; import { ProblemManager as TheiaProblemManager } from '@theia/markers/lib/browser';
@@ -160,7 +152,7 @@ import {
OutputChannelRegistryMainImpl as TheiaOutputChannelRegistryMainImpl, OutputChannelRegistryMainImpl as TheiaOutputChannelRegistryMainImpl,
OutputChannelRegistryMainImpl, OutputChannelRegistryMainImpl,
} from './theia/plugin-ext/output-channel-registry-main'; } from './theia/plugin-ext/output-channel-registry-main';
import { ExecutableService, ExecutableServicePath } from '../common/protocol'; import { ExecutableService, ExecutableServicePath, MonitorManagerProxy, MonitorManagerProxyClient, MonitorManagerProxyFactory, MonitorManagerProxyPath } from '../common/protocol';
import { MonacoTextModelService as TheiaMonacoTextModelService } from '@theia/monaco/lib/browser/monaco-text-model-service'; import { MonacoTextModelService as TheiaMonacoTextModelService } from '@theia/monaco/lib/browser/monaco-text-model-service';
import { MonacoTextModelService } from './theia/monaco/monaco-text-model-service'; import { MonacoTextModelService } from './theia/monaco/monaco-text-model-service';
import { ResponseServiceImpl } from './response-service-impl'; import { ResponseServiceImpl } from './response-service-impl';
@@ -275,6 +267,8 @@ import {
IDEUpdaterDialogWidget, IDEUpdaterDialogWidget,
} from './dialogs/ide-updater/ide-updater-dialog'; } from './dialogs/ide-updater/ide-updater-dialog';
import { ElectronIpcConnectionProvider } from '@theia/core/lib/electron-browser/messaging/electron-ipc-connection-provider'; import { ElectronIpcConnectionProvider } from '@theia/core/lib/electron-browser/messaging/electron-ipc-connection-provider';
import { MonitorModel } from './monitor-model';
import { MonitorManagerProxyClientImpl } from './monitor-manager-proxy-client-impl';
const ElementQueries = require('css-element-queries/src/ElementQueries'); const ElementQueries = require('css-element-queries/src/ElementQueries');
@@ -407,29 +401,31 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
.inSingletonScope(); .inSingletonScope();
// Serial monitor // Serial monitor
bind(SerialModel).toSelf().inSingletonScope();
bind(FrontendApplicationContribution).toService(SerialModel);
bind(MonitorWidget).toSelf(); bind(MonitorWidget).toSelf();
bind(FrontendApplicationContribution).toService(MonitorModel);
bind(MonitorModel).toSelf().inSingletonScope();
bindViewContribution(bind, MonitorViewContribution); bindViewContribution(bind, MonitorViewContribution);
bind(TabBarToolbarContribution).toService(MonitorViewContribution); bind(TabBarToolbarContribution).toService(MonitorViewContribution);
bind(WidgetFactory).toDynamicValue((context) => ({ bind(WidgetFactory).toDynamicValue((context) => ({
id: MonitorWidget.ID, id: MonitorWidget.ID,
createWidget: () => context.container.get(MonitorWidget), createWidget: () => {
})); return new MonitorWidget(
// Frontend binding for the serial service context.container.get<MonitorModel>(MonitorModel),
bind(SerialService) context.container.get<MonitorManagerProxyClient>(MonitorManagerProxyClient),
.toDynamicValue((context) => { context.container.get<BoardsServiceProvider>(BoardsServiceProvider),
const connection = context.container.get(WebSocketConnectionProvider);
const client = context.container.get<SerialServiceClient>(
SerialServiceClient
); );
return connection.createProxy(SerialServicePath, client); }
}) }));
.inSingletonScope();
bind(SerialConnectionManager).toSelf().inSingletonScope();
// Serial service client to receive and delegate notifications from the backend. bind(MonitorManagerProxyFactory).toFactory((context) => () => context.container.get<MonitorManagerProxy>(MonitorManagerProxy))
bind(SerialServiceClient).to(SerialServiceClientImpl).inSingletonScope();
bind(MonitorManagerProxy).toDynamicValue((context) =>
WebSocketConnectionProvider.createProxy(context.container, MonitorManagerProxyPath, context.container.get(MonitorManagerProxyClient))
).inSingletonScope();
// Monitor manager proxy client to receive and delegate pluggable monitors
// notifications from the backend
bind(MonitorManagerProxyClient).to(MonitorManagerProxyClientImpl).inSingletonScope();
bind(WorkspaceService).toSelf().inSingletonScope(); bind(WorkspaceService).toSelf().inSingletonScope();
rebind(TheiaWorkspaceService).toService(WorkspaceService); rebind(TheiaWorkspaceService).toService(WorkspaceService);

View File

@@ -3,7 +3,6 @@ import { OutputChannelManager } from '@theia/output/lib/browser/output-channel';
import { CoreService } from '../../common/protocol'; import { CoreService } from '../../common/protocol';
import { ArduinoMenus } from '../menu/arduino-menus'; import { ArduinoMenus } from '../menu/arduino-menus';
import { BoardsDataStore } from '../boards/boards-data-store'; import { BoardsDataStore } from '../boards/boards-data-store';
import { SerialConnectionManager } from '../serial/serial-connection-manager';
import { BoardsServiceProvider } from '../boards/boards-service-provider'; import { BoardsServiceProvider } from '../boards/boards-service-provider';
import { import {
SketchContribution, SketchContribution,
@@ -18,8 +17,6 @@ export class BurnBootloader extends SketchContribution {
@inject(CoreService) @inject(CoreService)
protected readonly coreService: CoreService; protected readonly coreService: CoreService;
@inject(SerialConnectionManager)
protected readonly serialConnection: SerialConnectionManager;
@inject(BoardsDataStore) @inject(BoardsDataStore)
protected readonly boardsDataStore: BoardsDataStore; protected readonly boardsDataStore: BoardsDataStore;
@@ -60,9 +57,15 @@ export class BurnBootloader extends SketchContribution {
this.preferences.get('arduino.upload.verify'), this.preferences.get('arduino.upload.verify'),
this.preferences.get('arduino.upload.verbose'), this.preferences.get('arduino.upload.verbose'),
]); ]);
const board = {
...boardsConfig.selectedBoard,
name: boardsConfig.selectedBoard?.name || '',
fqbn,
}
this.outputChannelManager.getChannel('Arduino').clear(); this.outputChannelManager.getChannel('Arduino').clear();
await this.coreService.burnBootloader({ await this.coreService.burnBootloader({
fqbn, board,
programmer, programmer,
port, port,
verify, verify,
@@ -85,8 +88,6 @@ export class BurnBootloader extends SketchContribution {
errorMessage = e.toString(); errorMessage = e.toString();
} }
this.messageService.error(errorMessage); this.messageService.error(errorMessage);
} finally {
await this.serialConnection.reconnectAfterUpload();
} }
} }
} }

View File

@@ -1,4 +1,4 @@
import { injectable } from 'inversify'; import { inject, injectable } from 'inversify';
import * as remote from '@theia/core/electron-shared/@electron/remote'; import * as remote from '@theia/core/electron-shared/@electron/remote';
import * as dateFormat from 'dateformat'; import * as dateFormat from 'dateformat';
import { ArduinoMenus } from '../menu/arduino-menus'; import { ArduinoMenus } from '../menu/arduino-menus';
@@ -11,9 +11,22 @@ import {
KeybindingRegistry, KeybindingRegistry,
} from './contribution'; } from './contribution';
import { nls } from '@theia/core/lib/common'; import { nls } from '@theia/core/lib/common';
import { ApplicationShell, NavigatableWidget, Saveable } from '@theia/core/lib/browser';
import { EditorManager } from '@theia/editor/lib/browser';
import { WindowService } from '@theia/core/lib/browser/window/window-service';
@injectable() @injectable()
export class SaveAsSketch extends SketchContribution { export class SaveAsSketch extends SketchContribution {
@inject(ApplicationShell)
protected readonly applicationShell: ApplicationShell;
@inject(EditorManager)
protected readonly editorManager: EditorManager;
@inject(WindowService)
protected readonly windowService: WindowService;
registerCommands(registry: CommandRegistry): void { registerCommands(registry: CommandRegistry): void {
registry.registerCommand(SaveAsSketch.Commands.SAVE_AS_SKETCH, { registry.registerCommand(SaveAsSketch.Commands.SAVE_AS_SKETCH, {
execute: (args) => this.saveAs(args), execute: (args) => this.saveAs(args),
@@ -90,6 +103,9 @@ export class SaveAsSketch extends SketchContribution {
const workspaceUri = await this.sketchService.copy(sketch, { const workspaceUri = await this.sketchService.copy(sketch, {
destinationUri, destinationUri,
}); });
if (workspaceUri) {
await this.saveOntoCopiedSketch(sketch.mainFileUri, sketch.uri, workspaceUri);
}
if (workspaceUri && openAfterMove) { if (workspaceUri && openAfterMove) {
if (wipeOriginal || (openAfterMove && execOnlyIfTemp)) { if (wipeOriginal || (openAfterMove && execOnlyIfTemp)) {
try { try {
@@ -100,12 +116,48 @@ export class SaveAsSketch extends SketchContribution {
/* NOOP: from time to time, it's not possible to wipe the old resource from the temp dir on Windows */ /* NOOP: from time to time, it's not possible to wipe the old resource from the temp dir on Windows */
} }
} }
this.windowService.setSafeToShutDown();
this.workspaceService.open(new URI(workspaceUri), { this.workspaceService.open(new URI(workspaceUri), {
preserveWindow: true, preserveWindow: true,
}); });
} }
return !!workspaceUri; return !!workspaceUri;
} }
private async saveOntoCopiedSketch(mainFileUri: string, sketchUri: string, newSketchUri: string): Promise<void> {
const widgets = this.applicationShell.widgets;
const snapshots = new Map<string, object>();
for (const widget of widgets) {
const saveable = Saveable.getDirty(widget);
const uri = NavigatableWidget.getUri(widget);
const uriString = uri?.toString();
let relativePath: string;
if (uri && uriString!.includes(sketchUri) && saveable && saveable.createSnapshot) {
// The main file will change its name during the copy process
// We need to store the new name in the map
if (mainFileUri === uriString) {
const lastPart = new URI(newSketchUri).path.base + uri.path.ext;
relativePath = '/' + lastPart;
} else {
relativePath = uri.toString().substring(sketchUri.length);
}
snapshots.set(relativePath, saveable.createSnapshot());
}
}
await Promise.all(Array.from(snapshots.entries()).map(async ([path, snapshot]) => {
const widgetUri = new URI(newSketchUri + path);
try {
const widget = await this.editorManager.getOrCreateByUri(widgetUri);
const saveable = Saveable.get(widget);
if (saveable && saveable.applySnapshot) {
saveable.applySnapshot(snapshot);
await saveable.save();
}
} catch (e) {
console.error(e);
}
}));
}
} }
export namespace SaveAsSketch { export namespace SaveAsSketch {

View File

@@ -4,7 +4,6 @@ import { BoardUserField, CoreService } from '../../common/protocol';
import { ArduinoMenus, PlaceholderMenuNode } from '../menu/arduino-menus'; import { ArduinoMenus, PlaceholderMenuNode } from '../menu/arduino-menus';
import { ArduinoToolbar } from '../toolbar/arduino-toolbar'; import { ArduinoToolbar } from '../toolbar/arduino-toolbar';
import { BoardsDataStore } from '../boards/boards-data-store'; import { BoardsDataStore } from '../boards/boards-data-store';
import { SerialConnectionManager } from '../serial/serial-connection-manager';
import { BoardsServiceProvider } from '../boards/boards-service-provider'; import { BoardsServiceProvider } from '../boards/boards-service-provider';
import { import {
SketchContribution, SketchContribution,
@@ -22,9 +21,6 @@ export class UploadSketch extends SketchContribution {
@inject(CoreService) @inject(CoreService)
protected readonly coreService: CoreService; protected readonly coreService: CoreService;
@inject(SerialConnectionManager)
protected readonly serialConnection: SerialConnectionManager;
@inject(MenuModelRegistry) @inject(MenuModelRegistry)
protected readonly menuRegistry: MenuModelRegistry; protected readonly menuRegistry: MenuModelRegistry;
@@ -226,6 +222,11 @@ export class UploadSketch extends SketchContribution {
this.sourceOverride(), this.sourceOverride(),
]); ]);
const board = {
...boardsConfig.selectedBoard,
name: boardsConfig.selectedBoard?.name || '',
fqbn,
}
let options: CoreService.Upload.Options | undefined = undefined; let options: CoreService.Upload.Options | undefined = undefined;
const sketchUri = sketch.uri; const sketchUri = sketch.uri;
const optimizeForDebug = this.editorMode.compileForDebug; const optimizeForDebug = this.editorMode.compileForDebug;
@@ -247,7 +248,7 @@ export class UploadSketch extends SketchContribution {
const programmer = selectedProgrammer; const programmer = selectedProgrammer;
options = { options = {
sketchUri, sketchUri,
fqbn, board,
optimizeForDebug, optimizeForDebug,
programmer, programmer,
port, port,
@@ -259,7 +260,7 @@ export class UploadSketch extends SketchContribution {
} else { } else {
options = { options = {
sketchUri, sketchUri,
fqbn, board,
optimizeForDebug, optimizeForDebug,
port, port,
verbose, verbose,
@@ -289,8 +290,6 @@ export class UploadSketch extends SketchContribution {
} finally { } finally {
this.uploadInProgress = false; this.uploadInProgress = false;
this.onDidChangeEmitter.fire(); this.onDidChangeEmitter.fire();
setTimeout(() => this.serialConnection.reconnectAfterUpload(), 5000);
} }
} }
} }

View File

@@ -110,12 +110,17 @@ export class VerifySketch extends SketchContribution {
), ),
this.sourceOverride(), this.sourceOverride(),
]); ]);
const board = {
...boardsConfig.selectedBoard,
name: boardsConfig.selectedBoard?.name || '',
fqbn,
}
const verbose = this.preferences.get('arduino.compile.verbose'); const verbose = this.preferences.get('arduino.compile.verbose');
const compilerWarnings = this.preferences.get('arduino.compile.warnings'); const compilerWarnings = this.preferences.get('arduino.compile.warnings');
this.outputChannelManager.getChannel('Arduino').clear(); this.outputChannelManager.getChannel('Arduino').clear();
await this.coreService.compile({ await this.coreService.compile({
sketchUri: sketch.uri, sketchUri: sketch.uri,
fqbn, board,
optimizeForDebug: this.editorMode.compileForDebug, optimizeForDebug: this.editorMode.compileForDebug,
verbose, verbose,
exportBinaries, exportBinaries,

View File

@@ -1,5 +1,6 @@
import { nls } from '@theia/core/lib/common'; import { nls } from '@theia/core/lib/common';
import * as React from 'react'; import * as React from 'react';
import { Port } from '../../../common/protocol';
import { import {
ArduinoFirmwareUploader, ArduinoFirmwareUploader,
FirmwareInfo, FirmwareInfo,
@@ -20,7 +21,7 @@ export const FirmwareUploaderComponent = ({
availableBoards: AvailableBoard[]; availableBoards: AvailableBoard[];
firmwareUploader: ArduinoFirmwareUploader; firmwareUploader: ArduinoFirmwareUploader;
updatableFqbns: string[]; updatableFqbns: string[];
flashFirmware: (firmware: FirmwareInfo, port: string) => Promise<any>; flashFirmware: (firmware: FirmwareInfo, port: Port) => Promise<any>;
isOpen: any; isOpen: any;
}): React.ReactElement => { }): React.ReactElement => {
// boolean states for buttons // boolean states for buttons
@@ -81,7 +82,7 @@ export const FirmwareUploaderComponent = ({
const installStatus = const installStatus =
!!firmwareToFlash && !!firmwareToFlash &&
!!selectedBoard?.port && !!selectedBoard?.port &&
(await flashFirmware(firmwareToFlash, selectedBoard?.port.address)); (await flashFirmware(firmwareToFlash, selectedBoard?.port));
setInstallFeedback((installStatus && 'ok') || 'fail'); setInstallFeedback((installStatus && 'ok') || 'fail');
} catch { } catch {

View File

@@ -15,6 +15,7 @@ import {
} from '../../../common/protocol/arduino-firmware-uploader'; } from '../../../common/protocol/arduino-firmware-uploader';
import { FirmwareUploaderComponent } from './firmware-uploader-component'; import { FirmwareUploaderComponent } from './firmware-uploader-component';
import { UploadFirmware } from '../../contributions/upload-firmware'; import { UploadFirmware } from '../../contributions/upload-firmware';
import { Port } from '../../../common/protocol';
@injectable() @injectable()
export class UploadFirmwareDialogWidget extends ReactWidget { export class UploadFirmwareDialogWidget extends ReactWidget {
@@ -49,7 +50,7 @@ export class UploadFirmwareDialogWidget extends ReactWidget {
}); });
} }
protected flashFirmware(firmware: FirmwareInfo, port: string): Promise<any> { protected flashFirmware(firmware: FirmwareInfo, port: Port): Promise<any> {
this.busyCallback(true); this.busyCallback(true);
return this.arduinoFirmwareUploader return this.arduinoFirmwareUploader
.flash(firmware, port) .flash(firmware, port)

View File

@@ -0,0 +1,127 @@
import { Emitter, MessageService } from '@theia/core';
import { inject, injectable } from '@theia/core/shared/inversify';
import { Board, Port } from '../common/protocol';
import {
Monitor,
MonitorManagerProxyClient,
MonitorManagerProxyFactory,
} from '../common/protocol/monitor-service';
import {
PluggableMonitorSettings,
MonitorSettings,
} from '../node/monitor-settings/monitor-settings-provider';
@injectable()
export class MonitorManagerProxyClientImpl
implements MonitorManagerProxyClient
{
// When pluggable monitor messages are received from the backend
// this event is triggered.
// Ideally a frontend component is connected to this event
// to update the UI.
protected readonly onMessagesReceivedEmitter = new Emitter<{
messages: string[];
}>();
readonly onMessagesReceived = this.onMessagesReceivedEmitter.event;
protected readonly onWSConnectionChangedEmitter = new Emitter<boolean>();
readonly onWSConnectionChanged = this.onWSConnectionChangedEmitter.event;
// WebSocket used to handle pluggable monitor communication between
// frontend and backend.
private webSocket?: WebSocket;
private wsPort?: number;
getWebSocketPort(): number | undefined {
return this.wsPort;
}
constructor(
@inject(MessageService)
protected messageService: MessageService,
// This is necessary to call the backend methods from the frontend
@inject(MonitorManagerProxyFactory)
protected server: MonitorManagerProxyFactory
) {}
/**
* Connects a localhost WebSocket using the specified port.
* @param addressPort port of the WebSocket
*/
connect(addressPort: number): void {
if (this.webSocket) {
return;
}
try {
this.webSocket = new WebSocket(`ws://localhost:${addressPort}`);
this.onWSConnectionChangedEmitter.fire(true);
} catch {
this.messageService.error('Unable to connect to websocket');
return;
}
this.webSocket.onmessage = (res) => {
const messages = JSON.parse(res.data);
this.onMessagesReceivedEmitter.fire({ messages });
};
this.wsPort = addressPort;
}
/**
* Disconnects the WebSocket if connected.
*/
disconnect(): void {
try {
this.webSocket?.close();
this.webSocket = undefined;
this.onWSConnectionChangedEmitter.fire(false);
} catch {
this.messageService.error('Unable to close websocket');
}
}
async isWSConnected(): Promise<boolean> {
return !!this.webSocket;
}
async startMonitor(
board: Board,
port: Port,
settings?: PluggableMonitorSettings
): Promise<void> {
return this.server().startMonitor(board, port, settings);
}
getCurrentSettings(board: Board, port: Port): MonitorSettings {
return this.server().getCurrentSettings(board, port);
}
send(message: string): void {
if (!this.webSocket) {
return;
}
this.webSocket.send(
JSON.stringify({
command: Monitor.Command.SEND_MESSAGE,
data: message,
})
);
}
changeSettings(settings: MonitorSettings): void {
if (!this.webSocket) {
return;
}
this.webSocket.send(
JSON.stringify({
command: Monitor.Command.CHANGE_SETTINGS,
// TODO: This might be wrong, verify if it works
// SPOILER: It doesn't
data: settings,
})
);
}
}

View File

@@ -1,69 +1,78 @@
import { injectable, inject } from 'inversify'; import { Emitter, Event } from '@theia/core';
import { Emitter, Event } from '@theia/core/lib/common/event';
import { SerialConfig } from '../../common/protocol';
import { import {
FrontendApplicationContribution, FrontendApplicationContribution,
LocalStorageService, LocalStorageService,
} from '@theia/core/lib/browser'; } from '@theia/core/lib/browser';
import { BoardsServiceProvider } from '../boards/boards-service-provider'; import { inject, injectable } from '@theia/core/shared/inversify';
@injectable() @injectable()
export class SerialModel implements FrontendApplicationContribution { export class MonitorModel implements FrontendApplicationContribution {
protected static STORAGE_ID = 'arduino-serial-model'; protected static STORAGE_ID = 'arduino-monitor-model';
@inject(LocalStorageService) @inject(LocalStorageService)
protected readonly localStorageService: LocalStorageService; protected readonly localStorageService: LocalStorageService;
@inject(BoardsServiceProvider)
protected readonly boardsServiceClient: BoardsServiceProvider;
protected readonly onChangeEmitter: Emitter< protected readonly onChangeEmitter: Emitter<
SerialModel.State.Change<keyof SerialModel.State> MonitorModel.State.Change<keyof MonitorModel.State>
>; >;
protected _autoscroll: boolean; protected _autoscroll: boolean;
protected _timestamp: boolean; protected _timestamp: boolean;
protected _baudRate: SerialConfig.BaudRate; protected _lineEnding: MonitorModel.EOL;
protected _lineEnding: SerialModel.EOL;
protected _interpolate: boolean; protected _interpolate: boolean;
constructor() { constructor() {
this._autoscroll = true; this._autoscroll = true;
this._timestamp = false; this._timestamp = false;
this._baudRate = SerialConfig.BaudRate.DEFAULT;
this._lineEnding = SerialModel.EOL.DEFAULT;
this._interpolate = false; this._interpolate = false;
this._lineEnding = MonitorModel.EOL.DEFAULT;
this.onChangeEmitter = new Emitter< this.onChangeEmitter = new Emitter<
SerialModel.State.Change<keyof SerialModel.State> MonitorModel.State.Change<keyof MonitorModel.State>
>(); >();
} }
onStart(): void { onStart(): void {
this.localStorageService this.localStorageService
.getData<SerialModel.State>(SerialModel.STORAGE_ID) .getData<MonitorModel.State>(MonitorModel.STORAGE_ID)
.then((state) => { .then(this.restoreState);
if (state) {
this.restoreState(state);
}
});
} }
get onChange(): Event<SerialModel.State.Change<keyof SerialModel.State>> { get onChange(): Event<MonitorModel.State.Change<keyof MonitorModel.State>> {
return this.onChangeEmitter.event; return this.onChangeEmitter.event;
} }
protected restoreState(state: MonitorModel.State): void {
if (!state) {
return;
}
this._autoscroll = state.autoscroll;
this._timestamp = state.timestamp;
this._lineEnding = state.lineEnding;
this._interpolate = state.interpolate;
}
protected async storeState(): Promise<void> {
return this.localStorageService.setData(MonitorModel.STORAGE_ID, {
autoscroll: this._autoscroll,
timestamp: this._timestamp,
lineEnding: this._lineEnding,
interpolate: this._interpolate,
});
}
get autoscroll(): boolean { get autoscroll(): boolean {
return this._autoscroll; return this._autoscroll;
} }
toggleAutoscroll(): void { toggleAutoscroll(): void {
this._autoscroll = !this._autoscroll; this._autoscroll = !this._autoscroll;
this.storeState(); this.storeState().then(() => {
this.storeState().then(() =>
this.onChangeEmitter.fire({ this.onChangeEmitter.fire({
property: 'autoscroll', property: 'autoscroll',
value: this._autoscroll, value: this._timestamp,
}) });
); });
} }
get timestamp(): boolean { get timestamp(): boolean {
@@ -80,25 +89,11 @@ export class SerialModel implements FrontendApplicationContribution {
); );
} }
get baudRate(): SerialConfig.BaudRate { get lineEnding(): MonitorModel.EOL {
return this._baudRate;
}
set baudRate(baudRate: SerialConfig.BaudRate) {
this._baudRate = baudRate;
this.storeState().then(() =>
this.onChangeEmitter.fire({
property: 'baudRate',
value: this._baudRate,
})
);
}
get lineEnding(): SerialModel.EOL {
return this._lineEnding; return this._lineEnding;
} }
set lineEnding(lineEnding: SerialModel.EOL) { set lineEnding(lineEnding: MonitorModel.EOL) {
this._lineEnding = lineEnding; this._lineEnding = lineEnding;
this.storeState().then(() => this.storeState().then(() =>
this.onChangeEmitter.fire({ this.onChangeEmitter.fire({
@@ -121,31 +116,13 @@ export class SerialModel implements FrontendApplicationContribution {
}) })
); );
} }
protected restoreState(state: SerialModel.State): void {
this._autoscroll = state.autoscroll;
this._timestamp = state.timestamp;
this._baudRate = state.baudRate;
this._lineEnding = state.lineEnding;
this._interpolate = state.interpolate;
}
protected async storeState(): Promise<void> {
return this.localStorageService.setData(SerialModel.STORAGE_ID, {
autoscroll: this._autoscroll,
timestamp: this._timestamp,
baudRate: this._baudRate,
lineEnding: this._lineEnding,
interpolate: this._interpolate,
});
}
} }
export namespace SerialModel { // TODO: Move this to /common
export namespace MonitorModel {
export interface State { export interface State {
autoscroll: boolean; autoscroll: boolean;
timestamp: boolean; timestamp: boolean;
baudRate: SerialConfig.BaudRate;
lineEnding: EOL; lineEnding: EOL;
interpolate: boolean; interpolate: boolean;
} }

View File

@@ -8,9 +8,9 @@ import {
TabBarToolbarRegistry, TabBarToolbarRegistry,
} from '@theia/core/lib/browser/shell/tab-bar-toolbar'; } from '@theia/core/lib/browser/shell/tab-bar-toolbar';
import { ArduinoToolbar } from '../../toolbar/arduino-toolbar'; import { ArduinoToolbar } from '../../toolbar/arduino-toolbar';
import { SerialModel } from '../serial-model';
import { ArduinoMenus } from '../../menu/arduino-menus'; import { ArduinoMenus } from '../../menu/arduino-menus';
import { nls } from '@theia/core/lib/common'; import { nls } from '@theia/core/lib/common';
import { MonitorModel } from '../../monitor-model';
export namespace SerialMonitor { export namespace SerialMonitor {
export namespace Commands { export namespace Commands {
@@ -48,7 +48,8 @@ export class MonitorViewContribution
static readonly TOGGLE_SERIAL_MONITOR_TOOLBAR = static readonly TOGGLE_SERIAL_MONITOR_TOOLBAR =
MonitorWidget.ID + ':toggle-toolbar'; MonitorWidget.ID + ':toggle-toolbar';
@inject(SerialModel) protected readonly model: SerialModel; @inject(MonitorModel)
protected readonly model: MonitorModel;
constructor() { constructor() {
super({ super({

View File

@@ -9,14 +9,14 @@ import {
Widget, Widget,
MessageLoop, MessageLoop,
} from '@theia/core/lib/browser/widgets'; } from '@theia/core/lib/browser/widgets';
import { SerialConfig } from '../../../common/protocol/serial-service';
import { ArduinoSelect } from '../../widgets/arduino-select'; import { ArduinoSelect } from '../../widgets/arduino-select';
import { SerialModel } from '../serial-model';
import { SerialConnectionManager } from '../serial-connection-manager';
import { SerialMonitorSendInput } from './serial-monitor-send-input'; import { SerialMonitorSendInput } from './serial-monitor-send-input';
import { SerialMonitorOutput } from './serial-monitor-send-output'; import { SerialMonitorOutput } from './serial-monitor-send-output';
import { BoardsServiceProvider } from '../../boards/boards-service-provider'; import { BoardsServiceProvider } from '../../boards/boards-service-provider';
import { nls } from '@theia/core/lib/common'; import { nls } from '@theia/core/lib/common';
import { MonitorManagerProxyClient } from '../../../common/protocol';
import { MonitorModel } from '../../monitor-model';
import { MonitorSettings } from '../../../node/monitor-settings/monitor-settings-provider';
@injectable() @injectable()
export class MonitorWidget extends ReactWidget { export class MonitorWidget extends ReactWidget {
@@ -26,15 +26,6 @@ export class MonitorWidget extends ReactWidget {
); );
static readonly ID = 'serial-monitor'; static readonly ID = 'serial-monitor';
@inject(SerialModel)
protected readonly serialModel: SerialModel;
@inject(SerialConnectionManager)
protected readonly serialConnection: SerialConnectionManager;
@inject(BoardsServiceProvider)
protected readonly boardsServiceProvider: BoardsServiceProvider;
protected widgetHeight: number; protected widgetHeight: number;
/** /**
@@ -48,7 +39,16 @@ export class MonitorWidget extends ReactWidget {
protected closing = false; protected closing = false;
protected readonly clearOutputEmitter = new Emitter<void>(); protected readonly clearOutputEmitter = new Emitter<void>();
constructor() { constructor(
@inject(MonitorModel)
protected readonly monitorModel: MonitorModel,
@inject(MonitorManagerProxyClient)
protected readonly monitorManagerProxy: MonitorManagerProxyClient,
@inject(BoardsServiceProvider)
protected readonly boardsServiceProvider: BoardsServiceProvider
) {
super(); super();
this.id = MonitorWidget.ID; this.id = MonitorWidget.ID;
this.title.label = MonitorWidget.LABEL; this.title.label = MonitorWidget.LABEL;
@@ -57,17 +57,35 @@ export class MonitorWidget extends ReactWidget {
this.scrollOptions = undefined; this.scrollOptions = undefined;
this.toDispose.push(this.clearOutputEmitter); this.toDispose.push(this.clearOutputEmitter);
this.toDispose.push( this.toDispose.push(
Disposable.create(() => this.serialConnection.closeWStoBE()) Disposable.create(() => this.monitorManagerProxy.disconnect())
);
// Start monitor right away if there is already a board/port combination selected
const { selectedBoard, selectedPort } =
this.boardsServiceProvider.boardsConfig;
if (selectedBoard && selectedBoard.fqbn && selectedPort) {
this.monitorManagerProxy.startMonitor(selectedBoard, selectedPort);
}
this.toDispose.push(
this.boardsServiceProvider.onBoardsConfigChanged(
async ({ selectedBoard, selectedPort }) => {
if (selectedBoard && selectedBoard.fqbn && selectedPort) {
await this.monitorManagerProxy.startMonitor(
selectedBoard,
selectedPort
);
this.update();
}
}
)
); );
} }
@postConstruct() @postConstruct()
protected init(): void { protected init(): void {
this.update(); this.update();
this.toDispose.push( this.toDispose.push(this.monitorModel.onChange(() => this.update()));
this.serialConnection.onConnectionChanged(() => this.clearConsole())
);
this.toDispose.push(this.serialModel.onChange(() => this.update()));
} }
clearConsole(): void { clearConsole(): void {
@@ -79,11 +97,6 @@ export class MonitorWidget extends ReactWidget {
super.dispose(); super.dispose();
} }
protected onAfterAttach(msg: Message): void {
super.onAfterAttach(msg);
this.serialConnection.openWSToBE();
}
onCloseRequest(msg: Message): void { onCloseRequest(msg: Message): void {
this.closing = true; this.closing = true;
super.onCloseRequest(msg); super.onCloseRequest(msg);
@@ -119,7 +132,7 @@ export class MonitorWidget extends ReactWidget {
}; };
protected get lineEndings(): OptionsType< protected get lineEndings(): OptionsType<
SerialMonitorOutput.SelectOption<SerialModel.EOL> SerialMonitorOutput.SelectOption<MonitorModel.EOL>
> { > {
return [ return [
{ {
@@ -144,32 +157,63 @@ export class MonitorWidget extends ReactWidget {
]; ];
} }
protected get baudRates(): OptionsType< private getCurrentSettings(): MonitorSettings {
SerialMonitorOutput.SelectOption<SerialConfig.BaudRate> const board = this.boardsServiceProvider.boardsConfig.selectedBoard;
> { const port = this.boardsServiceProvider.boardsConfig.selectedPort;
const baudRates: Array<SerialConfig.BaudRate> = [ if (!board || !port) {
300, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200, return {};
]; }
return baudRates.map((baudRate) => ({ return this.monitorManagerProxy.getCurrentSettings(board, port);
label: baudRate + ' baud', }
value: baudRate,
})); //////////////////////////////////////////////////
////////////////////IMPORTANT/////////////////////
//////////////////////////////////////////////////
// baudRates and selectedBaudRates as of now are hardcoded
// like this to retrieve the baudrate settings from the ones
// received by the monitor.
// We're doing it like since the frontend as of now doesn't
// support a fully customizable list of options that would
// be require to support pluggable monitors completely.
// As soon as the frontend UI is updated to support
// any custom settings this methods MUST be removed and
// made generic.
//
// This breaks if the user tries to open a monitor that
// doesn't support the baudrate setting.
protected get baudRates(): string[] {
const { pluggableMonitorSettings } = this.getCurrentSettings();
if (!pluggableMonitorSettings || !pluggableMonitorSettings['baudrate']) {
return [];
}
const baudRateSettings = pluggableMonitorSettings['baudrate'];
return baudRateSettings.values;
}
protected get selectedBaudRate(): string {
const { pluggableMonitorSettings } = this.getCurrentSettings();
if (!pluggableMonitorSettings || !pluggableMonitorSettings['baudrate']) {
return '';
}
const baudRateSettings = pluggableMonitorSettings['baudrate'];
return baudRateSettings.selectedValue;
} }
protected render(): React.ReactNode { protected render(): React.ReactNode {
const { baudRates, lineEndings } = this; const { baudRates, lineEndings } = this;
const lineEnding = const lineEnding =
lineEndings.find((item) => item.value === this.serialModel.lineEnding) || lineEndings.find((item) => item.value === this.monitorModel.lineEnding) ||
lineEndings[1]; // Defaults to `\n`. lineEndings[1]; // Defaults to `\n`.
const baudRate = const baudRate = baudRates.find((item) => item === this.selectedBaudRate);
baudRates.find((item) => item.value === this.serialModel.baudRate) ||
baudRates[4]; // Defaults to `9600`.
return ( return (
<div className="serial-monitor"> <div className="serial-monitor">
<div className="head"> <div className="head">
<div className="send"> <div className="send">
<SerialMonitorSendInput <SerialMonitorSendInput
serialConnection={this.serialConnection} boardsServiceProvider={this.boardsServiceProvider}
monitorManagerProxy={this.monitorManagerProxy}
resolveFocus={this.onFocusResolved} resolveFocus={this.onFocusResolved}
onSend={this.onSend} onSend={this.onSend}
/> />
@@ -196,8 +240,8 @@ export class MonitorWidget extends ReactWidget {
</div> </div>
<div className="body"> <div className="body">
<SerialMonitorOutput <SerialMonitorOutput
serialModel={this.serialModel} monitorModel={this.monitorModel}
serialConnection={this.serialConnection} monitorManagerProxy={this.monitorManagerProxy}
clearConsoleEvent={this.clearOutputEmitter.event} clearConsoleEvent={this.clearOutputEmitter.event}
height={Math.floor(this.widgetHeight - 50)} height={Math.floor(this.widgetHeight - 50)}
/> />
@@ -208,18 +252,21 @@ export class MonitorWidget extends ReactWidget {
protected readonly onSend = (value: string) => this.doSend(value); protected readonly onSend = (value: string) => this.doSend(value);
protected async doSend(value: string): Promise<void> { protected async doSend(value: string): Promise<void> {
this.serialConnection.send(value); this.monitorManagerProxy.send(value);
} }
protected readonly onChangeLineEnding = ( protected readonly onChangeLineEnding = (
option: SerialMonitorOutput.SelectOption<SerialModel.EOL> option: SerialMonitorOutput.SelectOption<MonitorModel.EOL>
) => { ) => {
this.serialModel.lineEnding = option.value; this.monitorModel.lineEnding = option.value;
}; };
protected readonly onChangeBaudRate = ( protected readonly onChangeBaudRate = (value: string) => {
option: SerialMonitorOutput.SelectOption<SerialConfig.BaudRate> const { pluggableMonitorSettings } = this.getCurrentSettings();
) => { if (!pluggableMonitorSettings || !pluggableMonitorSettings['baudrate'])
this.serialModel.baudRate = option.value; return;
const baudRateSettings = pluggableMonitorSettings['baudrate'];
baudRateSettings.selectedValue = value;
this.monitorManagerProxy.changeSettings(pluggableMonitorSettings);
}; };
} }

View File

@@ -3,12 +3,14 @@ import { Key, KeyCode } from '@theia/core/lib/browser/keys';
import { Board } from '../../../common/protocol/boards-service'; import { Board } from '../../../common/protocol/boards-service';
import { isOSX } from '@theia/core/lib/common/os'; import { isOSX } from '@theia/core/lib/common/os';
import { DisposableCollection, nls } from '@theia/core/lib/common'; import { DisposableCollection, nls } from '@theia/core/lib/common';
import { SerialConnectionManager } from '../serial-connection-manager'; import { MonitorManagerProxyClient } from '../../../common/protocol';
import { SerialPlotter } from '../plotter/protocol'; import { BoardsServiceProvider } from '../../boards/boards-service-provider';
import { timeout } from '@theia/core/lib/common/promise-util';
export namespace SerialMonitorSendInput { export namespace SerialMonitorSendInput {
export interface Props { export interface Props {
readonly serialConnection: SerialConnectionManager; readonly boardsServiceProvider: BoardsServiceProvider;
readonly monitorManagerProxy: MonitorManagerProxyClient;
readonly onSend: (text: string) => void; readonly onSend: (text: string) => void;
readonly resolveFocus: (element: HTMLElement | undefined) => void; readonly resolveFocus: (element: HTMLElement | undefined) => void;
} }
@@ -26,28 +28,33 @@ export class SerialMonitorSendInput extends React.Component<
constructor(props: Readonly<SerialMonitorSendInput.Props>) { constructor(props: Readonly<SerialMonitorSendInput.Props>) {
super(props); super(props);
this.state = { text: '', connected: false }; this.state = { text: '', connected: true };
this.onChange = this.onChange.bind(this); this.onChange = this.onChange.bind(this);
this.onSend = this.onSend.bind(this); this.onSend = this.onSend.bind(this);
this.onKeyDown = this.onKeyDown.bind(this); this.onKeyDown = this.onKeyDown.bind(this);
} }
componentDidMount(): void { componentDidMount(): void {
this.props.serialConnection.isBESerialConnected().then((connected) => { this.setState({ connected: true });
this.setState({ connected });
const checkWSConnection = new Promise<boolean>((resolve) => {
this.props.monitorManagerProxy.onWSConnectionChanged((connected) => {
this.setState({ connected });
resolve(true);
});
}); });
this.toDisposeBeforeUnmount.pushAll([ const checkWSTimeout = timeout(1000).then(() => false);
this.props.serialConnection.onRead(({ messages }) => {
if ( Promise.race<boolean>([checkWSConnection, checkWSTimeout]).then(
messages.command === async (resolved) => {
SerialPlotter.Protocol.Command.MIDDLEWARE_CONFIG_CHANGED && if (!resolved) {
'connected' in messages.data const connected =
) { await this.props.monitorManagerProxy.isWSConnected();
this.setState({ connected: messages.data.connected }); this.setState({ connected });
} }
}), }
]); );
} }
componentWillUnmount(): void { componentWillUnmount(): void {
@@ -60,7 +67,7 @@ export class SerialMonitorSendInput extends React.Component<
<input <input
ref={this.setRef} ref={this.setRef}
type="text" type="text"
className={`theia-input ${this.state.connected ? '' : 'warning'}`} className={`theia-input ${this.shouldShowWarning() ? 'warning' : ''}`}
placeholder={this.placeholder} placeholder={this.placeholder}
value={this.state.text} value={this.state.text}
onChange={this.onChange} onChange={this.onChange}
@@ -69,15 +76,22 @@ export class SerialMonitorSendInput extends React.Component<
); );
} }
protected shouldShowWarning(): boolean {
const board = this.props.boardsServiceProvider.boardsConfig.selectedBoard;
const port = this.props.boardsServiceProvider.boardsConfig.selectedPort;
return !this.state.connected || !board || !port;
}
protected get placeholder(): string { protected get placeholder(): string {
const serialConfig = this.props.serialConnection.getConfig(); if (this.shouldShowWarning()) {
if (!this.state.connected || !serialConfig) {
return nls.localize( return nls.localize(
'arduino/serial/notConnected', 'arduino/serial/notConnected',
'Not connected. Select a board and a port to connect automatically.' 'Not connected. Select a board and a port to connect automatically.'
); );
} }
const { board, port } = serialConfig;
const board = this.props.boardsServiceProvider.boardsConfig.selectedBoard;
const port = this.props.boardsServiceProvider.boardsConfig.selectedPort;
return nls.localize( return nls.localize(
'arduino/serial/message', 'arduino/serial/message',
"Message ({0} + Enter to send message to '{1}' on '{2}')", "Message ({0} + Enter to send message to '{1}' on '{2}')",

View File

@@ -2,10 +2,10 @@ import * as React from 'react';
import { Event } from '@theia/core/lib/common/event'; import { Event } from '@theia/core/lib/common/event';
import { DisposableCollection } from '@theia/core/lib/common/disposable'; import { DisposableCollection } from '@theia/core/lib/common/disposable';
import { areEqual, FixedSizeList as List } from 'react-window'; import { areEqual, FixedSizeList as List } from 'react-window';
import { SerialModel } from '../serial-model';
import { SerialConnectionManager } from '../serial-connection-manager';
import dateFormat = require('dateformat'); import dateFormat = require('dateformat');
import { messagesToLines, truncateLines } from './monitor-utils'; import { messagesToLines, truncateLines } from './monitor-utils';
import { MonitorManagerProxyClient } from '../../../common/protocol';
import { MonitorModel } from '../../monitor-model';
export type Line = { message: string; timestamp?: Date; lineLen: number }; export type Line = { message: string; timestamp?: Date; lineLen: number };
@@ -24,7 +24,7 @@ export class SerialMonitorOutput extends React.Component<
this.listRef = React.createRef(); this.listRef = React.createRef();
this.state = { this.state = {
lines: [], lines: [],
timestamp: this.props.serialModel.timestamp, timestamp: this.props.monitorModel.timestamp,
charCount: 0, charCount: 0,
}; };
} }
@@ -58,14 +58,13 @@ export class SerialMonitorOutput extends React.Component<
componentDidMount(): void { componentDidMount(): void {
this.scrollToBottom(); this.scrollToBottom();
this.toDisposeBeforeUnmount.pushAll([ this.toDisposeBeforeUnmount.pushAll([
this.props.serialConnection.onRead(({ messages }) => { this.props.monitorManagerProxy.onMessagesReceived(({ messages }) => {
const [newLines, totalCharCount] = messagesToLines( const [newLines, totalCharCount] = messagesToLines(
messages, messages,
this.state.lines, this.state.lines,
this.state.charCount this.state.charCount
); );
const [lines, charCount] = truncateLines(newLines, totalCharCount); const [lines, charCount] = truncateLines(newLines, totalCharCount);
this.setState({ this.setState({
lines, lines,
charCount, charCount,
@@ -75,9 +74,9 @@ export class SerialMonitorOutput extends React.Component<
this.props.clearConsoleEvent(() => this.props.clearConsoleEvent(() =>
this.setState({ lines: [], charCount: 0 }) this.setState({ lines: [], charCount: 0 })
), ),
this.props.serialModel.onChange(({ property }) => { this.props.monitorModel.onChange(({ property }) => {
if (property === 'timestamp') { if (property === 'timestamp') {
const { timestamp } = this.props.serialModel; const { timestamp } = this.props.monitorModel;
this.setState({ timestamp }); this.setState({ timestamp });
} }
if (property === 'autoscroll') { if (property === 'autoscroll') {
@@ -93,7 +92,7 @@ export class SerialMonitorOutput extends React.Component<
} }
scrollToBottom = ((): void => { scrollToBottom = ((): void => {
if (this.listRef.current && this.props.serialModel.autoscroll) { if (this.listRef.current && this.props.monitorModel.autoscroll) {
this.listRef.current.scrollToItem(this.state.lines.length, 'end'); this.listRef.current.scrollToItem(this.state.lines.length, 'end');
} }
}).bind(this); }).bind(this);
@@ -128,8 +127,8 @@ const Row = React.memo(_Row, areEqual);
export namespace SerialMonitorOutput { export namespace SerialMonitorOutput {
export interface Props { export interface Props {
readonly serialModel: SerialModel; readonly monitorModel: MonitorModel;
readonly serialConnection: SerialConnectionManager; readonly monitorManagerProxy: MonitorManagerProxyClient;
readonly clearConsoleEvent: Event<void>; readonly clearConsoleEvent: Event<void>;
readonly height: number; readonly height: number;
} }

View File

@@ -6,15 +6,14 @@ import {
MaybePromise, MaybePromise,
MenuModelRegistry, MenuModelRegistry,
} from '@theia/core'; } from '@theia/core';
import { SerialModel } from '../serial-model';
import { ArduinoMenus } from '../../menu/arduino-menus'; import { ArduinoMenus } from '../../menu/arduino-menus';
import { Contribution } from '../../contributions/contribution'; import { Contribution } from '../../contributions/contribution';
import { Endpoint, FrontendApplication } from '@theia/core/lib/browser'; import { Endpoint, FrontendApplication } from '@theia/core/lib/browser';
import { ipcRenderer } from '@theia/electron/shared/electron'; import { ipcRenderer } from '@theia/electron/shared/electron';
import { SerialConfig } from '../../../common/protocol'; import { MonitorManagerProxyClient } from '../../../common/protocol';
import { SerialConnectionManager } from '../serial-connection-manager';
import { SerialPlotter } from './protocol'; import { SerialPlotter } from './protocol';
import { BoardsServiceProvider } from '../../boards/boards-service-provider'; import { BoardsServiceProvider } from '../../boards/boards-service-provider';
import { MonitorModel } from '../../monitor-model';
const queryString = require('query-string'); const queryString = require('query-string');
export namespace SerialPlotterContribution { export namespace SerialPlotterContribution {
@@ -33,14 +32,14 @@ export class PlotterFrontendContribution extends Contribution {
protected url: string; protected url: string;
protected wsPort: number; protected wsPort: number;
@inject(SerialModel) @inject(MonitorModel)
protected readonly model: SerialModel; protected readonly model: MonitorModel;
@inject(ThemeService) @inject(ThemeService)
protected readonly themeService: ThemeService; protected readonly themeService: ThemeService;
@inject(SerialConnectionManager) @inject(MonitorManagerProxyClient)
protected readonly serialConnection: SerialConnectionManager; protected readonly monitorManagerProxy: MonitorManagerProxyClient;
@inject(BoardsServiceProvider) @inject(BoardsServiceProvider)
protected readonly boardsServiceProvider: BoardsServiceProvider; protected readonly boardsServiceProvider: BoardsServiceProvider;
@@ -75,7 +74,7 @@ export class PlotterFrontendContribution extends Contribution {
this.window.focus(); this.window.focus();
return; return;
} }
const wsPort = this.serialConnection.getWsPort(); const wsPort = this.monitorManagerProxy.getWebSocketPort();
if (wsPort) { if (wsPort) {
this.open(wsPort); this.open(wsPort);
} else { } else {
@@ -84,14 +83,28 @@ export class PlotterFrontendContribution extends Contribution {
} }
protected async open(wsPort: number): Promise<void> { protected async open(wsPort: number): Promise<void> {
const board = this.boardsServiceProvider.boardsConfig.selectedBoard;
const port = this.boardsServiceProvider.boardsConfig.selectedPort;
let baudrates: number[] = [];
let currentBaudrate = -1;
if (board && port) {
const { pluggableMonitorSettings } =
this.monitorManagerProxy.getCurrentSettings(board, port);
if (pluggableMonitorSettings && 'baudrate' in pluggableMonitorSettings) {
// Convert from string to numbers
baudrates = pluggableMonitorSettings['baudrate'].values.map((b) => +b);
currentBaudrate = +pluggableMonitorSettings['baudrate'].selectedValue;
}
}
const initConfig: Partial<SerialPlotter.Config> = { const initConfig: Partial<SerialPlotter.Config> = {
baudrates: SerialConfig.BaudRates.map((b) => b), baudrates,
currentBaudrate: this.model.baudRate, currentBaudrate,
currentLineEnding: this.model.lineEnding, currentLineEnding: this.model.lineEnding,
darkTheme: this.themeService.getCurrentTheme().type === 'dark', darkTheme: this.themeService.getCurrentTheme().type === 'dark',
wsPort, wsPort,
interpolate: this.model.interpolate, interpolate: this.model.interpolate,
connected: await this.serialConnection.isBESerialConnected(), connected: await this.monitorManagerProxy.isWSConnected(),
serialPort: this.boardsServiceProvider.boardsConfig.selectedPort?.address, serialPort: this.boardsServiceProvider.boardsConfig.selectedPort?.address,
}; };
const urlWithParams = queryString.stringifyUrl( const urlWithParams = queryString.stringifyUrl(

View File

@@ -1,360 +0,0 @@
import { injectable, inject } from 'inversify';
import { Emitter, Event } from '@theia/core/lib/common/event';
import { MessageService } from '@theia/core/lib/common/message-service';
import {
SerialService,
SerialConfig,
SerialError,
Status,
SerialServiceClient,
} from '../../common/protocol/serial-service';
import { BoardsServiceProvider } from '../boards/boards-service-provider';
import {
Board,
BoardsService,
} from '../../common/protocol/boards-service';
import { BoardsConfig } from '../boards/boards-config';
import { SerialModel } from './serial-model';
import { ThemeService } from '@theia/core/lib/browser/theming';
import { CoreService } from '../../common/protocol';
import { nls } from '@theia/core/lib/common/nls';
@injectable()
export class SerialConnectionManager {
protected config: Partial<SerialConfig> = {
board: undefined,
port: undefined,
baudRate: undefined,
};
protected readonly onConnectionChangedEmitter = new Emitter<boolean>();
/**
* This emitter forwards all read events **if** the connection is established.
*/
protected readonly onReadEmitter = new Emitter<{ messages: string[] }>();
/**
* Array for storing previous serial errors received from the server, and based on the number of elements in this array,
* we adjust the reconnection delay.
* Super naive way: we wait `array.length * 1000` ms. Once we hit 10 errors, we do not try to reconnect and clean the array.
*/
protected serialErrors: SerialError[] = [];
protected reconnectTimeout?: number;
/**
* When the websocket server is up on the backend, we save the port here, so that the client knows how to connect to it
* */
protected wsPort?: number;
protected webSocket?: WebSocket;
constructor(
@inject(SerialModel) protected readonly serialModel: SerialModel,
@inject(SerialService) protected readonly serialService: SerialService,
@inject(SerialServiceClient)
protected readonly serialServiceClient: SerialServiceClient,
@inject(BoardsService) protected readonly boardsService: BoardsService,
@inject(BoardsServiceProvider)
protected readonly boardsServiceProvider: BoardsServiceProvider,
@inject(MessageService) protected messageService: MessageService,
@inject(ThemeService) protected readonly themeService: ThemeService,
@inject(CoreService) protected readonly core: CoreService,
@inject(BoardsServiceProvider)
protected readonly boardsServiceClientImpl: BoardsServiceProvider
) {
this.serialServiceClient.onWebSocketChanged(
this.handleWebSocketChanged.bind(this)
);
this.serialServiceClient.onBaudRateChanged((baudRate) => {
if (this.serialModel.baudRate !== baudRate) {
this.serialModel.baudRate = baudRate;
}
});
this.serialServiceClient.onLineEndingChanged((lineending) => {
if (this.serialModel.lineEnding !== lineending) {
this.serialModel.lineEnding = lineending;
}
});
this.serialServiceClient.onInterpolateChanged((interpolate) => {
if (this.serialModel.interpolate !== interpolate) {
this.serialModel.interpolate = interpolate;
}
});
this.serialServiceClient.onError(this.handleError.bind(this));
this.boardsServiceProvider.onBoardsConfigChanged(
this.handleBoardConfigChange.bind(this)
);
// Handles the `baudRate` changes by reconnecting if required.
this.serialModel.onChange(async ({ property }) => {
if (
property === 'baudRate' &&
(await this.serialService.isSerialPortOpen())
) {
const { boardsConfig } = this.boardsServiceProvider;
this.handleBoardConfigChange(boardsConfig);
}
// update the current values in the backend and propagate to websocket clients
this.serialService.updateWsConfigParam({
...(property === 'lineEnding' && {
currentLineEnding: this.serialModel.lineEnding,
}),
...(property === 'interpolate' && {
interpolate: this.serialModel.interpolate,
}),
});
});
this.themeService.onDidColorThemeChange((theme) => {
this.serialService.updateWsConfigParam({
darkTheme: theme.newTheme.type === 'dark',
});
});
}
/**
* Updated the config in the BE passing only the properties that has changed.
* BE will create a new connection if needed.
*
* @param newConfig the porperties of the config that has changed
*/
async setConfig(newConfig: Partial<SerialConfig>): Promise<void> {
let configHasChanged = false;
Object.keys(this.config).forEach((key: keyof SerialConfig) => {
if (newConfig[key] !== this.config[key]) {
configHasChanged = true;
this.config = { ...this.config, [key]: newConfig[key] };
}
});
if (configHasChanged) {
this.serialService.updateWsConfigParam({
currentBaudrate: this.config.baudRate,
serialPort: this.config.port?.address,
});
if (isSerialConfig(this.config)) {
this.serialService.setSerialConfig(this.config);
}
}
}
getConfig(): Partial<SerialConfig> {
return this.config;
}
getWsPort(): number | undefined {
return this.wsPort;
}
protected handleWebSocketChanged(wsPort: number): void {
this.wsPort = wsPort;
}
get serialConfig(): SerialConfig | undefined {
return isSerialConfig(this.config)
? (this.config as SerialConfig)
: undefined;
}
async isBESerialConnected(): Promise<boolean> {
return await this.serialService.isSerialPortOpen();
}
openWSToBE(): void {
if (!isSerialConfig(this.config)) {
this.messageService.error(
`Please select a board and a port to open the serial connection.`
);
}
if (!this.webSocket && this.wsPort) {
try {
this.webSocket = new WebSocket(`ws://localhost:${this.wsPort}`);
this.webSocket.onmessage = (res) => {
const messages = JSON.parse(res.data);
this.onReadEmitter.fire({ messages });
};
} catch {
this.messageService.error(`Unable to connect to websocket`);
}
}
}
closeWStoBE(): void {
if (this.webSocket) {
try {
this.webSocket.close();
this.webSocket = undefined;
} catch {
this.messageService.error(`Unable to close websocket`);
}
}
}
/**
* Handles error on the SerialServiceClient and try to reconnect, eventually
*/
async handleError(error: SerialError): Promise<void> {
if (!(await this.serialService.isSerialPortOpen())) return;
const { code, config } = error;
const { board, port } = config;
const options = { timeout: 3000 };
switch (code) {
case SerialError.ErrorCodes.CLIENT_CANCEL: {
console.debug(
`Serial connection was canceled by client: ${Serial.Config.toString(
this.config
)}.`
);
break;
}
case SerialError.ErrorCodes.DEVICE_BUSY: {
this.messageService.warn(
nls.localize(
'arduino/serial/connectionBusy',
'Connection failed. Serial port is busy: {0}',
port.address
),
options
);
this.serialErrors.push(error);
break;
}
case SerialError.ErrorCodes.DEVICE_NOT_CONFIGURED: {
this.messageService.info(
nls.localize(
'arduino/serial/disconnected',
'Disconnected {0} from {1}.',
Board.toString(board, {
useFqbn: false,
}),
port.address
),
options
);
break;
}
case undefined: {
this.messageService.error(
nls.localize(
'arduino/serial/unexpectedError',
'Unexpected error. Reconnecting {0} on port {1}.',
Board.toString(board),
port.address
),
options
);
console.error(JSON.stringify(error));
break;
}
}
if ((await this.serialService.clientsAttached()) > 0) {
if (this.serialErrors.length >= 10) {
this.messageService.warn(
nls.localize(
'arduino/serial/failedReconnect',
'Failed to reconnect {0} to serial port after 10 consecutive attempts. The {1} serial port is busy.',
Board.toString(board, {
useFqbn: false,
}),
port.address
)
);
this.serialErrors.length = 0;
} else {
const attempts = this.serialErrors.length || 1;
if (this.reconnectTimeout !== undefined) {
// Clear the previous timer.
window.clearTimeout(this.reconnectTimeout);
}
const timeout = attempts * 1000;
this.messageService.warn(
nls.localize(
'arduino/serial/reconnect',
'Reconnecting {0} to {1} in {2} seconds...',
Board.toString(board, {
useFqbn: false,
}),
port.address,
attempts.toString()
)
);
this.reconnectTimeout = window.setTimeout(
() => this.reconnectAfterUpload(),
timeout
);
}
}
}
async reconnectAfterUpload(): Promise<void> {
try {
if (isSerialConfig(this.config)) {
await this.boardsServiceClientImpl.waitUntilAvailable(
Object.assign(this.config.board, { port: this.config.port }),
10_000
);
this.serialService.connectSerialIfRequired();
}
} catch (waitError) {
this.messageService.error(
nls.localize(
'arduino/sketch/couldNotConnectToSerial',
'Could not reconnect to serial port. {0}',
waitError.toString()
)
);
}
}
/**
* Sends the data to the connected serial port.
* The desired EOL is appended to `data`, you do not have to add it.
* It is a NOOP if connected.
*/
async send(data: string): Promise<Status> {
if (!(await this.serialService.isSerialPortOpen())) {
return Status.NOT_CONNECTED;
}
return new Promise<Status>((resolve) => {
this.serialService
.sendMessageToSerial(data + this.serialModel.lineEnding)
.then(() => resolve(Status.OK));
});
}
get onConnectionChanged(): Event<boolean> {
return this.onConnectionChangedEmitter.event;
}
get onRead(): Event<{ messages: any }> {
return this.onReadEmitter.event;
}
protected async handleBoardConfigChange(
boardsConfig: BoardsConfig.Config
): Promise<void> {
const { selectedBoard: board, selectedPort: port } = boardsConfig;
const { baudRate } = this.serialModel;
const newConfig: Partial<SerialConfig> = { board, port, baudRate };
this.setConfig(newConfig);
}
}
export namespace Serial {
export namespace Config {
export function toString(config: Partial<SerialConfig>): string {
if (!isSerialConfig(config)) return '';
const { board, port } = config;
return `${Board.toString(board)} ${port.address}`;
}
}
}
function isSerialConfig(config: Partial<SerialConfig>): config is SerialConfig {
return !!config.board && !!config.baudRate && !!config.port;
}

View File

@@ -1,48 +0,0 @@
import { injectable } from 'inversify';
import { Emitter } from '@theia/core/lib/common/event';
import {
SerialServiceClient,
SerialError,
SerialConfig,
} from '../../common/protocol/serial-service';
import { SerialModel } from './serial-model';
@injectable()
export class SerialServiceClientImpl implements SerialServiceClient {
protected readonly onErrorEmitter = new Emitter<SerialError>();
readonly onError = this.onErrorEmitter.event;
protected readonly onWebSocketChangedEmitter = new Emitter<number>();
readonly onWebSocketChanged = this.onWebSocketChangedEmitter.event;
protected readonly onBaudRateChangedEmitter =
new Emitter<SerialConfig.BaudRate>();
readonly onBaudRateChanged = this.onBaudRateChangedEmitter.event;
protected readonly onLineEndingChangedEmitter =
new Emitter<SerialModel.EOL>();
readonly onLineEndingChanged = this.onLineEndingChangedEmitter.event;
protected readonly onInterpolateChangedEmitter = new Emitter<boolean>();
readonly onInterpolateChanged = this.onInterpolateChangedEmitter.event;
notifyError(error: SerialError): void {
this.onErrorEmitter.fire(error);
}
notifyWebSocketChanged(message: number): void {
this.onWebSocketChangedEmitter.fire(message);
}
notifyBaudRateChanged(message: SerialConfig.BaudRate): void {
this.onBaudRateChangedEmitter.fire(message);
}
notifyLineEndingChanged(message: SerialModel.EOL): void {
this.onLineEndingChangedEmitter.fire(message);
}
notifyInterpolateChanged(message: boolean): void {
this.onInterpolateChangedEmitter.fire(message);
}
}

View File

@@ -1,3 +1,5 @@
import { Port } from "./boards-service";
export const ArduinoFirmwareUploaderPath = export const ArduinoFirmwareUploaderPath =
'/services/arduino-firmware-uploader'; '/services/arduino-firmware-uploader';
export const ArduinoFirmwareUploader = Symbol('ArduinoFirmwareUploader'); export const ArduinoFirmwareUploader = Symbol('ArduinoFirmwareUploader');
@@ -10,7 +12,7 @@ export type FirmwareInfo = {
}; };
export interface ArduinoFirmwareUploader { export interface ArduinoFirmwareUploader {
list(fqbn?: string): Promise<FirmwareInfo[]>; list(fqbn?: string): Promise<FirmwareInfo[]>;
flash(firmware: FirmwareInfo, port: string): Promise<string>; flash(firmware: FirmwareInfo, port: Port): Promise<string>;
uploadCertificates(command: string): Promise<any>; uploadCertificates(command: string): Promise<any>;
updatableBoards(): Promise<string[]>; updatableBoards(): Promise<string[]>;
availableFirmwares(fqbn: string): Promise<FirmwareInfo[]>; availableFirmwares(fqbn: string): Promise<FirmwareInfo[]>;

View File

@@ -1,5 +1,5 @@
import { BoardUserField } from '.'; import { BoardUserField } from '.';
import { Port } from '../../common/protocol/boards-service'; import { Board, Port } from '../../common/protocol/boards-service';
import { Programmer } from './boards-service'; import { Programmer } from './boards-service';
export const CompilerWarningLiterals = [ export const CompilerWarningLiterals = [
@@ -33,7 +33,7 @@ export namespace CoreService {
* `file` URI to the sketch folder. * `file` URI to the sketch folder.
*/ */
readonly sketchUri: string; readonly sketchUri: string;
readonly fqbn?: string | undefined; readonly board?: Board;
readonly optimizeForDebug: boolean; readonly optimizeForDebug: boolean;
readonly verbose: boolean; readonly verbose: boolean;
readonly sourceOverride: Record<string, string>; readonly sourceOverride: Record<string, string>;
@@ -42,7 +42,7 @@ export namespace CoreService {
export namespace Upload { export namespace Upload {
export interface Options extends Compile.Options { export interface Options extends Compile.Options {
readonly port?: Port | undefined; readonly port?: Port;
readonly programmer?: Programmer | undefined; readonly programmer?: Programmer | undefined;
readonly verify: boolean; readonly verify: boolean;
readonly userFields: BoardUserField[]; readonly userFields: BoardUserField[];
@@ -51,8 +51,8 @@ export namespace CoreService {
export namespace Bootloader { export namespace Bootloader {
export interface Options { export interface Options {
readonly fqbn?: string | undefined; readonly board?: Board;
readonly port?: Port | undefined; readonly port?: Port;
readonly programmer?: Programmer | undefined; readonly programmer?: Programmer | undefined;
readonly verbose: boolean; readonly verbose: boolean;
readonly verify: boolean; readonly verify: boolean;

View File

@@ -6,10 +6,10 @@ export * from './core-service';
export * from './filesystem-ext'; export * from './filesystem-ext';
export * from './installable'; export * from './installable';
export * from './library-service'; export * from './library-service';
export * from './serial-service';
export * from './searchable'; export * from './searchable';
export * from './sketches-service'; export * from './sketches-service';
export * from './examples-service'; export * from './examples-service';
export * from './executable-service'; export * from './executable-service';
export * from './response-service'; export * from './response-service';
export * from './notification-service'; export * from './notification-service';
export * from './monitor-service';

View File

@@ -0,0 +1,92 @@
import { Event, JsonRpcServer } from '@theia/core';
import {
PluggableMonitorSettings,
MonitorSettings,
} from '../../node/monitor-settings/monitor-settings-provider';
import { Board, Port } from './boards-service';
export const MonitorManagerProxyFactory = Symbol('MonitorManagerProxyFactory');
export type MonitorManagerProxyFactory = () => MonitorManagerProxy;
export const MonitorManagerProxyPath = '/services/monitor-manager-proxy';
export const MonitorManagerProxy = Symbol('MonitorManagerProxy');
export interface MonitorManagerProxy
extends JsonRpcServer<MonitorManagerProxyClient> {
startMonitor(
board: Board,
port: Port,
settings?: PluggableMonitorSettings
): Promise<void>;
changeMonitorSettings(
board: Board,
port: Port,
settings: PluggableMonitorSettings
): Promise<void>;
stopMonitor(board: Board, port: Port): Promise<void>;
getCurrentSettings(board: Board, port: Port): PluggableMonitorSettings;
}
export const MonitorManagerProxyClient = Symbol('MonitorManagerProxyClient');
export interface MonitorManagerProxyClient {
onMessagesReceived: Event<{ messages: string[] }>;
onWSConnectionChanged: Event<boolean>;
connect(addressPort: number): void;
disconnect(): void;
getWebSocketPort(): number | undefined;
isWSConnected(): Promise<boolean>;
startMonitor(
board: Board,
port: Port,
settings?: PluggableMonitorSettings
): Promise<void>;
getCurrentSettings(board: Board, port: Port): MonitorSettings;
send(message: string): void;
changeSettings(settings: MonitorSettings): void;
}
export interface PluggableMonitorSetting {
// The setting identifier
readonly id: string;
// A human-readable label of the setting (to be displayed on the GUI)
readonly label: string;
// The setting type (at the moment only "enum" is avaiable)
readonly type: string;
// The values allowed on "enum" types
readonly values: string[];
// The selected value
selectedValue: string;
}
export namespace Monitor {
export enum Command {
SEND_MESSAGE = 'MONITOR_SEND_MESSAGE',
CHANGE_SETTINGS = 'MONITOR_CHANGE_SETTINGS',
}
export type Message = {
command: Monitor.Command;
data: string;
};
}
export interface Status {}
export type OK = Status;
export interface ErrorStatus extends Status {
readonly message: string;
}
export namespace Status {
export function isOK(status: Status & { message?: string }): status is OK {
return !!status && typeof status.message !== 'string';
}
export const OK: OK = {};
export const NOT_CONNECTED: ErrorStatus = { message: 'Not connected.' };
export const ALREADY_CONNECTED: ErrorStatus = {
message: 'Already connected.',
};
export const CONFIG_MISSING: ErrorStatus = {
message: 'Serial Config missing.',
};
export const UPLOAD_IN_PROGRESS: ErrorStatus = {
message: 'Upload in progress.',
};
}

View File

@@ -1,102 +0,0 @@
import { JsonRpcServer } from '@theia/core/lib/common/messaging/proxy-factory';
import { Board, Port } from './boards-service';
import { Event } from '@theia/core/lib/common/event';
import { SerialPlotter } from '../../browser/serial/plotter/protocol';
import { SerialModel } from '../../browser/serial/serial-model';
export interface Status {}
export type OK = Status;
export interface ErrorStatus extends Status {
readonly message: string;
}
export namespace Status {
export function isOK(status: Status & { message?: string }): status is OK {
return !!status && typeof status.message !== 'string';
}
export const OK: OK = {};
export const NOT_CONNECTED: ErrorStatus = { message: 'Not connected.' };
export const ALREADY_CONNECTED: ErrorStatus = {
message: 'Already connected.',
};
export const CONFIG_MISSING: ErrorStatus = {
message: 'Serial Config missing.',
};
}
export const SerialServicePath = '/services/serial';
export const SerialService = Symbol('SerialService');
export interface SerialService extends JsonRpcServer<SerialServiceClient> {
clientsAttached(): Promise<number>;
setSerialConfig(config: SerialConfig): Promise<void>;
sendMessageToSerial(message: string): Promise<Status>;
updateWsConfigParam(config: Partial<SerialPlotter.Config>): Promise<void>;
isSerialPortOpen(): Promise<boolean>;
connectSerialIfRequired(): Promise<void>;
disconnect(reason?: SerialError): Promise<Status>;
uploadInProgress: boolean;
}
export interface SerialConfig {
readonly board: Board;
readonly port: Port;
/**
* Defaults to [`SERIAL`](MonitorConfig#ConnectionType#SERIAL).
*/
readonly type?: SerialConfig.ConnectionType;
/**
* Defaults to `9600`.
*/
readonly baudRate?: SerialConfig.BaudRate;
}
export namespace SerialConfig {
export const BaudRates = [
300, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200,
] as const;
export type BaudRate = typeof SerialConfig.BaudRates[number];
export namespace BaudRate {
export const DEFAULT: BaudRate = 9600;
}
export enum ConnectionType {
SERIAL = 0,
}
}
export const SerialServiceClient = Symbol('SerialServiceClient');
export interface SerialServiceClient {
onError: Event<SerialError>;
onWebSocketChanged: Event<number>;
onLineEndingChanged: Event<SerialModel.EOL>;
onBaudRateChanged: Event<SerialConfig.BaudRate>;
onInterpolateChanged: Event<boolean>;
notifyError(event: SerialError): void;
notifyWebSocketChanged(message: number): void;
notifyLineEndingChanged(message: SerialModel.EOL): void;
notifyBaudRateChanged(message: SerialConfig.BaudRate): void;
notifyInterpolateChanged(message: boolean): void;
}
export interface SerialError {
readonly message: string;
/**
* If no `code` is available, clients must reestablish the serial connection.
*/
readonly code: number | undefined;
readonly config: SerialConfig;
}
export namespace SerialError {
export namespace ErrorCodes {
/**
* The frontend has refreshed the browser, for instance.
*/
export const CLIENT_CANCEL = 1;
/**
* When detaching a physical device when the duplex channel is still opened.
*/
export const DEVICE_NOT_CONFIGURED = 2;
/**
* Another serial connection was opened on this port. For another electron-instance, Java IDE.
*/
export const DEVICE_BUSY = 3;
}
}

View File

@@ -3,10 +3,10 @@ import {
FirmwareInfo, FirmwareInfo,
} from '../common/protocol/arduino-firmware-uploader'; } from '../common/protocol/arduino-firmware-uploader';
import { injectable, inject, named } from 'inversify'; import { injectable, inject, named } from 'inversify';
import { ExecutableService } from '../common/protocol'; import { ExecutableService, Port } from '../common/protocol';
import { SerialService } from '../common/protocol/serial-service';
import { getExecPath, spawnCommand } from './exec-util'; import { getExecPath, spawnCommand } from './exec-util';
import { ILogger } from '@theia/core/lib/common/logger'; import { ILogger } from '@theia/core/lib/common/logger';
import { MonitorManager } from './monitor-manager';
@injectable() @injectable()
export class ArduinoFirmwareUploaderImpl implements ArduinoFirmwareUploader { export class ArduinoFirmwareUploaderImpl implements ArduinoFirmwareUploader {
@@ -19,8 +19,8 @@ export class ArduinoFirmwareUploaderImpl implements ArduinoFirmwareUploader {
@named('fwuploader') @named('fwuploader')
protected readonly logger: ILogger; protected readonly logger: ILogger;
@inject(SerialService) @inject(MonitorManager)
protected readonly serialService: SerialService; protected readonly monitorManager: MonitorManager;
protected onError(error: any): void { protected onError(error: any): void {
this.logger.error(error); this.logger.error(error);
@@ -69,26 +69,28 @@ export class ArduinoFirmwareUploaderImpl implements ArduinoFirmwareUploader {
return await this.list(fqbn); return await this.list(fqbn);
} }
async flash(firmware: FirmwareInfo, port: string): Promise<string> { async flash(firmware: FirmwareInfo, port: Port): Promise<string> {
let output; let output;
const board = {
name: firmware.board_name,
fqbn: firmware.board_fqbn,
}
try { try {
this.serialService.uploadInProgress = true; this.monitorManager.notifyUploadStarted(board, port);
await this.serialService.disconnect();
output = await this.runCommand([ output = await this.runCommand([
'firmware', 'firmware',
'flash', 'flash',
'--fqbn', '--fqbn',
firmware.board_fqbn, firmware.board_fqbn,
'--address', '--address',
port, port.address,
'--module', '--module',
`${firmware.module}@${firmware.firmware_version}`, `${firmware.module}@${firmware.firmware_version}`,
]); ]);
} catch (e) { } catch (e) {
throw e; throw e;
} finally { } finally {
this.serialService.uploadInProgress = false; this.monitorManager.notifyUploadFinished(board, port);
this.serialService.connectSerialIfRequired();
return output; return output;
} }
} }

View File

@@ -40,16 +40,7 @@ import {
ArduinoDaemon, ArduinoDaemon,
ArduinoDaemonPath, ArduinoDaemonPath,
} from '../common/protocol/arduino-daemon'; } from '../common/protocol/arduino-daemon';
import {
SerialServiceImpl,
SerialServiceName,
} from './serial/serial-service-impl';
import {
SerialService,
SerialServicePath,
SerialServiceClient,
} from '../common/protocol/serial-service';
import { MonitorClientProvider } from './serial/monitor-client-provider';
import { ConfigServiceImpl } from './config-service-impl'; import { ConfigServiceImpl } from './config-service-impl';
import { EnvVariablesServer as TheiaEnvVariablesServer } from '@theia/core/lib/common/env-variables'; import { EnvVariablesServer as TheiaEnvVariablesServer } from '@theia/core/lib/common/env-variables';
import { EnvVariablesServer } from './theia/env-variables/env-variables-server'; import { EnvVariablesServer } from './theia/env-variables/env-variables-server';
@@ -90,10 +81,24 @@ import {
} from '../common/protocol/authentication-service'; } from '../common/protocol/authentication-service';
import { ArduinoFirmwareUploaderImpl } from './arduino-firmware-uploader-impl'; import { ArduinoFirmwareUploaderImpl } from './arduino-firmware-uploader-impl';
import { PlotterBackendContribution } from './plotter/plotter-backend-contribution'; import { PlotterBackendContribution } from './plotter/plotter-backend-contribution';
import WebSocketServiceImpl from './web-socket/web-socket-service-impl';
import { WebSocketService } from './web-socket/web-socket-service';
import { ArduinoLocalizationContribution } from './arduino-localization-contribution'; import { ArduinoLocalizationContribution } from './arduino-localization-contribution';
import { LocalizationContribution } from '@theia/core/lib/node/i18n/localization-contribution'; import { LocalizationContribution } from '@theia/core/lib/node/i18n/localization-contribution';
import { MonitorManagerProxyImpl } from './monitor-manager-proxy-impl';
import { MonitorManager, MonitorManagerName } from './monitor-manager';
import {
MonitorManagerProxy,
MonitorManagerProxyClient,
MonitorManagerProxyPath,
} from '../common/protocol/monitor-service';
import { MonitorService, MonitorServiceName } from './monitor-service';
import { MonitorSettingsProvider } from './monitor-settings/monitor-settings-provider';
import { MonitorSettingsProviderImpl } from './monitor-settings/monitor-settings-provider-impl';
import {
MonitorServiceFactory,
MonitorServiceFactoryOptions,
} from './monitor-service-factory';
import WebSocketProviderImpl from './web-socket/web-socket-provider-impl';
import { WebSocketProvider } from './web-socket/web-socket-provider';
export default new ContainerModule((bind, unbind, isBound, rebind) => { export default new ContainerModule((bind, unbind, isBound, rebind) => {
bind(BackendApplication).toSelf().inSingletonScope(); bind(BackendApplication).toSelf().inSingletonScope();
@@ -177,9 +182,6 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
}) })
); );
// Shared WebSocketService for the backend. This will manage all websocket conenctions
bind(WebSocketService).to(WebSocketServiceImpl).inSingletonScope();
// Shared Arduino core client provider service for the backend. // Shared Arduino core client provider service for the backend.
bind(CoreClientProvider).toSelf().inSingletonScope(); bind(CoreClientProvider).toSelf().inSingletonScope();
@@ -205,19 +207,57 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
// #endregion Theia customizations // #endregion Theia customizations
// a single MonitorManager is responsible for handling the actual connections to the pluggable monitors
bind(MonitorManager).toSelf().inSingletonScope();
// monitor service & factory bindings
bind(MonitorSettingsProviderImpl).toSelf().inSingletonScope();
bind(MonitorSettingsProvider).toService(MonitorSettingsProviderImpl);
bind(WebSocketProviderImpl).toSelf();
bind(WebSocketProvider).toService(WebSocketProviderImpl);
bind(MonitorServiceFactory).toFactory(
({ container }) =>
(options: MonitorServiceFactoryOptions) => {
const logger = container.get<ILogger>(ILogger);
const monitorSettingsProvider = container.get<MonitorSettingsProvider>(
MonitorSettingsProvider
);
const webSocketProvider =
container.get<WebSocketProvider>(WebSocketProvider);
const { board, port, coreClientProvider } = options;
return new MonitorService(
logger,
monitorSettingsProvider,
webSocketProvider,
board,
port,
coreClientProvider
);
}
);
// Serial client provider per connected frontend. // Serial client provider per connected frontend.
bind(ConnectionContainerModule).toConstantValue( bind(ConnectionContainerModule).toConstantValue(
ConnectionContainerModule.create(({ bind, bindBackendService }) => { ConnectionContainerModule.create(({ bind, bindBackendService }) => {
bind(MonitorClientProvider).toSelf().inSingletonScope(); bind(MonitorManagerProxyImpl).toSelf().inSingletonScope();
bind(SerialServiceImpl).toSelf().inSingletonScope(); bind(MonitorManagerProxy).toService(MonitorManagerProxyImpl);
bind(SerialService).toService(SerialServiceImpl); bindBackendService<MonitorManagerProxy, MonitorManagerProxyClient>(
bindBackendService<SerialService, SerialServiceClient>( MonitorManagerProxyPath,
SerialServicePath, MonitorManagerProxy,
SerialService, (monitorMgrProxy, client) => {
(service, client) => { monitorMgrProxy.setClient(client);
service.setClient(client); // when the client close the connection, the proxy is disposed.
client.onDidCloseConnection(() => service.dispose()); // when the MonitorManagerProxy is disposed, it informs the MonitorManager
return service; // telling him that it does not need an address/board anymore.
// the MonitorManager will then dispose the actual connection if there are no proxies using it
client.onDidCloseConnection(() => monitorMgrProxy.dispose());
return monitorMgrProxy;
} }
); );
}) })
@@ -307,14 +347,22 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
.inSingletonScope() .inSingletonScope()
.whenTargetNamed('config'); .whenTargetNamed('config');
// Logger for the serial service. // Logger for the monitor manager and its services
bind(ILogger) bind(ILogger)
.toDynamicValue((ctx) => { .toDynamicValue((ctx) => {
const parentLogger = ctx.container.get<ILogger>(ILogger); const parentLogger = ctx.container.get<ILogger>(ILogger);
return parentLogger.child(SerialServiceName); return parentLogger.child(MonitorManagerName);
}) })
.inSingletonScope() .inSingletonScope()
.whenTargetNamed(SerialServiceName); .whenTargetNamed(MonitorManagerName);
bind(ILogger)
.toDynamicValue((ctx) => {
const parentLogger = ctx.container.get<ILogger>(ILogger);
return parentLogger.child(MonitorServiceName);
})
.inSingletonScope()
.whenTargetNamed(MonitorServiceName);
bind(DefaultGitInit).toSelf(); bind(DefaultGitInit).toSelf();
rebind(GitInit).toService(DefaultGitInit); rebind(GitInit).toService(DefaultGitInit);

View File

@@ -24,7 +24,7 @@ import { ArduinoCoreServiceClient } from './cli-protocol/cc/arduino/cli/commands
import { firstToUpperCase, firstToLowerCase } from '../common/utils'; import { firstToUpperCase, firstToLowerCase } from '../common/utils';
import { Port } from './cli-protocol/cc/arduino/cli/commands/v1/port_pb'; import { Port } from './cli-protocol/cc/arduino/cli/commands/v1/port_pb';
import { nls } from '@theia/core'; import { nls } from '@theia/core';
import { SerialService } from './../common/protocol/serial-service'; import { MonitorManager } from './monitor-manager';
@injectable() @injectable()
export class CoreServiceImpl extends CoreClientAware implements CoreService { export class CoreServiceImpl extends CoreClientAware implements CoreService {
@@ -34,8 +34,8 @@ export class CoreServiceImpl extends CoreClientAware implements CoreService {
@inject(NotificationServiceServer) @inject(NotificationServiceServer)
protected readonly notificationService: NotificationServiceServer; protected readonly notificationService: NotificationServiceServer;
@inject(SerialService) @inject(MonitorManager)
protected readonly serialService: SerialService; protected readonly monitorManager: MonitorManager;
protected uploading = false; protected uploading = false;
@@ -45,7 +45,7 @@ export class CoreServiceImpl extends CoreClientAware implements CoreService {
compilerWarnings?: CompilerWarnings; compilerWarnings?: CompilerWarnings;
} }
): Promise<void> { ): Promise<void> {
const { sketchUri, fqbn, compilerWarnings } = options; const { sketchUri, board, compilerWarnings } = options;
const sketchPath = FileUri.fsPath(sketchUri); const sketchPath = FileUri.fsPath(sketchUri);
await this.coreClientProvider.initialized; await this.coreClientProvider.initialized;
@@ -55,8 +55,8 @@ export class CoreServiceImpl extends CoreClientAware implements CoreService {
const compileReq = new CompileRequest(); const compileReq = new CompileRequest();
compileReq.setInstance(instance); compileReq.setInstance(instance);
compileReq.setSketchPath(sketchPath); compileReq.setSketchPath(sketchPath);
if (fqbn) { if (board?.fqbn) {
compileReq.setFqbn(fqbn); compileReq.setFqbn(board.fqbn);
} }
if (compilerWarnings) { if (compilerWarnings) {
compileReq.setWarnings(compilerWarnings.toLowerCase()); compileReq.setWarnings(compilerWarnings.toLowerCase());
@@ -139,11 +139,9 @@ export class CoreServiceImpl extends CoreClientAware implements CoreService {
await this.compile(Object.assign(options, { exportBinaries: false })); await this.compile(Object.assign(options, { exportBinaries: false }));
this.uploading = true; this.uploading = true;
this.serialService.uploadInProgress = true; const { sketchUri, board, port, programmer } = options;
await this.monitorManager.notifyUploadStarted(board, port);
await this.serialService.disconnect();
const { sketchUri, fqbn, port, programmer } = options;
const sketchPath = FileUri.fsPath(sketchUri); const sketchPath = FileUri.fsPath(sketchUri);
await this.coreClientProvider.initialized; await this.coreClientProvider.initialized;
@@ -153,8 +151,8 @@ export class CoreServiceImpl extends CoreClientAware implements CoreService {
const req = requestProvider(); const req = requestProvider();
req.setInstance(instance); req.setInstance(instance);
req.setSketchPath(sketchPath); req.setSketchPath(sketchPath);
if (fqbn) { if (board?.fqbn) {
req.setFqbn(fqbn); req.setFqbn(board.fqbn);
} }
const p = new Port(); const p = new Port();
if (port) { if (port) {
@@ -209,23 +207,22 @@ export class CoreServiceImpl extends CoreClientAware implements CoreService {
throw new Error(errorMessage); throw new Error(errorMessage);
} finally { } finally {
this.uploading = false; this.uploading = false;
this.serialService.uploadInProgress = false; this.monitorManager.notifyUploadFinished(board, port);
} }
} }
async burnBootloader(options: CoreService.Bootloader.Options): Promise<void> { async burnBootloader(options: CoreService.Bootloader.Options): Promise<void> {
this.uploading = true; this.uploading = true;
this.serialService.uploadInProgress = true; const { board, port, programmer } = options;
await this.serialService.disconnect(); await this.monitorManager.notifyUploadStarted(board, port);
await this.coreClientProvider.initialized; await this.coreClientProvider.initialized;
const coreClient = await this.coreClient(); const coreClient = await this.coreClient();
const { client, instance } = coreClient; const { client, instance } = coreClient;
const { fqbn, port, programmer } = options;
const burnReq = new BurnBootloaderRequest(); const burnReq = new BurnBootloaderRequest();
burnReq.setInstance(instance); burnReq.setInstance(instance);
if (fqbn) { if (board?.fqbn) {
burnReq.setFqbn(fqbn); burnReq.setFqbn(board.fqbn);
} }
const p = new Port(); const p = new Port();
if (port) { if (port) {
@@ -267,7 +264,7 @@ export class CoreServiceImpl extends CoreClientAware implements CoreService {
throw new Error(errorMessage); throw new Error(errorMessage);
} finally { } finally {
this.uploading = false; this.uploading = false;
this.serialService.uploadInProgress = false; await this.monitorManager.notifyUploadFinished(board, port);
} }
} }

View File

@@ -0,0 +1,92 @@
import { inject, injectable } from '@theia/core/shared/inversify';
import {
MonitorManagerProxy,
MonitorManagerProxyClient,
Status,
} from '../common/protocol';
import { Board, Port } from '../common/protocol';
import { MonitorManager } from './monitor-manager';
import { PluggableMonitorSettings } from './monitor-settings/monitor-settings-provider';
@injectable()
export class MonitorManagerProxyImpl implements MonitorManagerProxy {
protected client: MonitorManagerProxyClient;
constructor(
@inject(MonitorManager)
protected readonly manager: MonitorManager
) {}
dispose(): void {
this.client?.disconnect();
}
/**
* Start a pluggable monitor and/or change its settings.
* If settings are defined they'll be set before starting the monitor,
* otherwise default ones will be used by the monitor.
* @param board board connected to port
* @param port port to monitor
* @param settings map of supported configuration by the monitor
*/
async startMonitor(
board: Board,
port: Port,
settings?: PluggableMonitorSettings
): Promise<void> {
if (settings) {
await this.changeMonitorSettings(board, port, settings);
}
const status = await this.manager.startMonitor(board, port);
if (status === Status.ALREADY_CONNECTED || status === Status.OK) {
// Monitor started correctly, connect it with the frontend
this.client.connect(this.manager.getWebsocketAddressPort(board, port));
}
}
/**
* Changes the settings of a running pluggable monitor, if that monitor is not
* started this function is a noop.
* @param board board connected to port
* @param port port monitored
* @param settings map of supported configuration by the monitor
*/
async changeMonitorSettings(
board: Board,
port: Port,
settings: PluggableMonitorSettings
): Promise<void> {
if (!this.manager.isStarted(board, port)) {
// Monitor is not running, no need to change settings
return;
}
return this.manager.changeMonitorSettings(board, port, settings);
}
/**
* Stops a running pluggable monitor.
* @param board board connected to port
* @param port port monitored
*/
async stopMonitor(board: Board, port: Port): Promise<void> {
return this.manager.stopMonitor(board, port);
}
/**
* Returns the current settings by the pluggable monitor connected to specified
* by board/port combination.
* @param board board connected to port
* @param port port monitored
* @returns a map of MonitorSetting
*/
getCurrentSettings(board: Board, port: Port): PluggableMonitorSettings {
return this.manager.currentMonitorSettings(board, port);
}
setClient(client: MonitorManagerProxyClient | undefined): void {
if (!client) {
return;
}
this.client = client;
}
}

View File

@@ -0,0 +1,213 @@
import { ILogger } from '@theia/core';
import { inject, injectable, named } from '@theia/core/shared/inversify';
import { Board, Port, Status } from '../common/protocol';
import { CoreClientAware } from './core-client-provider';
import { MonitorService } from './monitor-service';
import { MonitorServiceFactory } from './monitor-service-factory';
import { PluggableMonitorSettings } from './monitor-settings/monitor-settings-provider';
type MonitorID = string;
export const MonitorManagerName = 'monitor-manager';
@injectable()
export class MonitorManager extends CoreClientAware {
// Map of monitor services that manage the running pluggable monitors.
// Each service handles the lifetime of one, and only one, monitor.
// If either the board or port managed changes, a new service must
// be started.
private monitorServices = new Map<MonitorID, MonitorService>();
@inject(MonitorServiceFactory)
private monitorServiceFactory: MonitorServiceFactory;
constructor(
@inject(ILogger)
@named(MonitorManagerName)
protected readonly logger: ILogger
) {
super();
}
/**
* Used to know if a monitor is started
* @param board board connected to port
* @param port port to monitor
* @returns true if the monitor is currently monitoring the board/port
* combination specifed, false in all other cases.
*/
isStarted(board: Board, port: Port): boolean {
const monitorID = this.monitorID(board, port);
const monitor = this.monitorServices.get(monitorID);
if (monitor) {
return monitor.isStarted();
}
return false;
}
/**
* Start a pluggable monitor that receives and sends messages
* to the specified board and port combination.
* @param board board connected to port
* @param port port to monitor
* @returns a Status object to know if the process has been
* started or if there have been errors.
*/
async startMonitor(board: Board, port: Port): Promise<Status> {
const monitorID = this.monitorID(board, port);
let monitor = this.monitorServices.get(monitorID);
if (!monitor) {
monitor = this.createMonitor(board, port);
}
return await monitor.start(monitorID);
}
/**
* Stop a pluggable monitor connected to the specified board/port
* combination. It's a noop if monitor is not running.
* @param board board connected to port
* @param port port monitored
*/
async stopMonitor(board: Board, port: Port): Promise<void> {
const monitorID = this.monitorID(board, port);
const monitor = this.monitorServices.get(monitorID);
if (!monitor) {
// There's no monitor to stop, bail
return;
}
return await monitor.stop();
}
/**
* Returns the port of the WebSocket used by the MonitorService
* that is handling the board/port combination
* @param board board connected to port
* @param port port to monitor
* @returns port of the MonitorService's WebSocket
*/
getWebsocketAddressPort(board: Board, port: Port): number {
const monitorID = this.monitorID(board, port);
const monitor = this.monitorServices.get(monitorID);
if (!monitor) {
return -1;
}
return monitor.getWebsocketAddressPort();
}
/**
* Notifies the monitor service of that board/port combination
* that an upload process started on that exact board/port combination.
* This must be done so that we can stop the monitor for the time being
* until the upload process finished.
* @param board board connected to port
* @param port port to monitor
*/
async notifyUploadStarted(board?: Board, port?: Port): Promise<void> {
if (!board || !port) {
// We have no way of knowing which monitor
// to retrieve if we don't have this information.
return;
}
const monitorID = this.monitorID(board, port);
const monitor = this.monitorServices.get(monitorID);
if (!monitor) {
// There's no monitor running there, bail
return;
}
monitor.setUploadInProgress(true);
return await monitor.pause();
}
/**
* Notifies the monitor service of that board/port combination
* that an upload process started on that exact board/port combination.
* @param board board connected to port
* @param port port to monitor
* @returns a Status object to know if the process has been
* started or if there have been errors.
*/
async notifyUploadFinished(board?: Board, port?: Port): Promise<Status> {
if (!board || !port) {
// We have no way of knowing which monitor
// to retrieve if we don't have this information.
return Status.NOT_CONNECTED;
}
const monitorID = this.monitorID(board, port);
const monitor = this.monitorServices.get(monitorID);
if (!monitor) {
// There's no monitor running there, bail
return Status.NOT_CONNECTED;
}
monitor.setUploadInProgress(false);
return await monitor.start(monitorID);
}
/**
* Changes the settings of a pluggable monitor even if it's running.
* If monitor is not running they're going to be used as soon as it's started.
* @param board board connected to port
* @param port port to monitor
* @param settings monitor settings to change
*/
changeMonitorSettings(
board: Board,
port: Port,
settings: PluggableMonitorSettings
) {
const monitorID = this.monitorID(board, port);
let monitor = this.monitorServices.get(monitorID);
if (!monitor) {
monitor = this.createMonitor(board, port);
monitor.changeSettings(settings);
}
}
/**
* Returns the settings currently used by the pluggable monitor
* that's communicating with the specified board/port combination.
* @param board board connected to port
* @param port port monitored
* @returns map of current monitor settings
*/
currentMonitorSettings(board: Board, port: Port): PluggableMonitorSettings {
const monitorID = this.monitorID(board, port);
const monitor = this.monitorServices.get(monitorID);
if (!monitor) {
return {};
}
return monitor.currentSettings();
}
/**
* Creates a MonitorService that handles the lifetime and the
* communication via WebSocket with the frontend.
* @param board board connected to specified port
* @param port port to monitor
* @returns a new instance of MonitorService ready to use.
*/
private createMonitor(board: Board, port: Port): MonitorService {
const monitorID = this.monitorID(board, port);
const monitor = this.monitorServiceFactory({
board,
port,
coreClientProvider: this.coreClientProvider,
});
this.monitorServices.set(monitorID, monitor);
monitor.onDispose(
(() => {
this.monitorServices.delete(monitorID);
}).bind(this)
);
return monitor;
}
/**
* Utility function to create a unique ID for a monitor service.
* @param board
* @param port
* @returns a unique monitor ID
*/
private monitorID(board: Board, port: Port): MonitorID {
return `${board.fqbn}-${port.address}-${port.protocol}`;
}
}

View File

@@ -0,0 +1,18 @@
import { Board, Port } from '../common/protocol';
import { CoreClientProvider } from './core-client-provider';
import { MonitorService } from './monitor-service';
export const MonitorServiceFactory = Symbol('MonitorServiceFactory');
export interface MonitorServiceFactory {
(options: {
board: Board;
port: Port;
coreClientProvider: CoreClientProvider;
}): MonitorService;
}
export interface MonitorServiceFactoryOptions {
board: Board;
port: Port;
coreClientProvider: CoreClientProvider;
}

View File

@@ -0,0 +1,425 @@
import { ClientDuplexStream } from '@grpc/grpc-js';
import { Disposable, Emitter, ILogger } from '@theia/core';
import { inject, named } from '@theia/core/shared/inversify';
import { Board, Port, Status, Monitor } from '../common/protocol';
import {
EnumerateMonitorPortSettingsRequest,
EnumerateMonitorPortSettingsResponse,
MonitorPortConfiguration,
MonitorPortSetting,
MonitorRequest,
MonitorResponse,
} from './cli-protocol/cc/arduino/cli/commands/v1/monitor_pb';
import { CoreClientAware, CoreClientProvider } from './core-client-provider';
import { WebSocketProvider } from './web-socket/web-socket-provider';
import { Port as gRPCPort } from 'arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/port_pb';
import {
PluggableMonitorSettings,
MonitorSettingsProvider,
} from './monitor-settings/monitor-settings-provider';
export const MonitorServiceName = 'monitor-service';
export class MonitorService extends CoreClientAware implements Disposable {
// Bidirectional gRPC stream used to receive and send data from the running
// pluggable monitor managed by the Arduino CLI.
protected duplex: ClientDuplexStream<MonitorRequest, MonitorResponse> | null;
// Settings used by the currently running pluggable monitor.
// They can be freely modified while running.
protected settings: PluggableMonitorSettings;
// List of messages received from the running pluggable monitor.
// These are flushed from time to time to the frontend.
protected messages: string[] = [];
// Handles messages received from the frontend via websocket.
protected onMessageReceived?: Disposable;
// Sends messages to the frontend from time to time.
protected flushMessagesInterval?: NodeJS.Timeout;
// Triggered each time the number of clients connected
// to the this service WebSocket changes.
protected onWSClientsNumberChanged?: Disposable;
// Used to notify that the monitor is being disposed
protected readonly onDisposeEmitter = new Emitter<void>();
readonly onDispose = this.onDisposeEmitter.event;
protected uploadInProgress = false;
constructor(
@inject(ILogger)
@named(MonitorServiceName)
protected readonly logger: ILogger,
@inject(MonitorSettingsProvider)
protected readonly monitorSettingsProvider: MonitorSettingsProvider,
@inject(WebSocketProvider)
protected readonly webSocketProvider: WebSocketProvider,
private readonly board: Board,
private readonly port: Port,
protected readonly coreClientProvider: CoreClientProvider
) {
super();
this.onWSClientsNumberChanged =
this.webSocketProvider.onClientsNumberChanged(async (clients: number) => {
if (clients === 0) {
// There are no more clients that want to receive
// data from this monitor, we can freely close
// and dispose it.
this.dispose();
}
});
}
setUploadInProgress(status: boolean): void {
this.uploadInProgress = status;
}
getWebsocketAddressPort(): number {
return this.webSocketProvider.getAddress().port;
}
dispose(): void {
this.stop();
this.onDisposeEmitter.fire();
}
/**
* isStarted is used to know if the currently running pluggable monitor is started.
* @returns true if pluggable monitor communication duplex is open,
* false in all other cases.
*/
isStarted(): boolean {
return !!this.duplex;
}
/**
* Start and connects a monitor using currently set board and port.
* If a monitor is already started or board fqbn, port address and/or protocol
* are missing nothing happens.
* @param id
* @returns a status to verify connection has been established.
*/
async start(monitorID: string): Promise<Status> {
if (this.duplex) {
return Status.ALREADY_CONNECTED;
}
if (!this.board?.fqbn || !this.port?.address || !this.port?.protocol) {
return Status.CONFIG_MISSING;
}
if (this.uploadInProgress) {
return Status.UPLOAD_IN_PROGRESS;
}
this.logger.info('starting monitor');
// get default monitor settings from the CLI
const defaultSettings = await this.portMonitorSettings(
this.port.protocol,
this.board.fqbn
);
// get actual settings from the settings provider
this.settings = await this.monitorSettingsProvider.getSettings(
monitorID,
defaultSettings
);
await this.coreClientProvider.initialized;
const coreClient = await this.coreClient();
const { client, instance } = coreClient;
this.duplex = client.monitor();
this.duplex
.on('close', () => {
this.duplex = null;
this.logger.info(
`monitor to ${this.port?.address} using ${this.port?.protocol} closed by client`
);
})
.on('end', () => {
this.duplex = null;
this.logger.info(
`monitor to ${this.port?.address} using ${this.port?.protocol} closed by server`
);
})
.on('error', (err: Error) => {
this.logger.error(err);
// TODO
// this.theiaFEClient?.notifyError()
})
.on(
'data',
((res: MonitorResponse) => {
if (res.getError()) {
// TODO: Maybe disconnect
this.logger.error(res.getError());
return;
}
const data = res.getRxData();
const message =
typeof data === 'string'
? data
: new TextDecoder('utf8').decode(data);
this.messages.push(...splitLines(message));
}).bind(this)
);
const req = new MonitorRequest();
req.setInstance(instance);
if (this.board?.fqbn) {
req.setFqbn(this.board.fqbn);
}
if (this.port?.address && this.port?.protocol) {
const port = new gRPCPort();
port.setAddress(this.port.address);
port.setProtocol(this.port.protocol);
req.setPort(port);
}
const config = new MonitorPortConfiguration();
for (const id in this.settings) {
const s = new MonitorPortSetting();
s.setSettingId(id);
s.setValue(this.settings[id].selectedValue);
config.addSettings(s);
}
req.setPortConfiguration(config);
const connect = new Promise<Status>((resolve) => {
if (this.duplex?.write(req)) {
this.startMessagesHandlers();
this.logger.info(
`started monitor to ${this.port?.address} using ${this.port?.protocol}`
);
resolve(Status.OK);
return;
}
this.logger.warn(
`failed starting monitor to ${this.port?.address} using ${this.port?.protocol}`
);
resolve(Status.NOT_CONNECTED);
});
const connectTimeout = new Promise<Status>((resolve) => {
setTimeout(async () => {
this.logger.warn(
`timeout starting monitor to ${this.port?.address} using ${this.port?.protocol}`
);
resolve(Status.NOT_CONNECTED);
}, 1000);
});
// Try opening a monitor connection with a timeout
return await Promise.race([connect, connectTimeout]);
}
/**
* Pauses the currently running monitor, it still closes the gRPC connection
* with the underlying monitor process but it doesn't stop the message handlers
* currently running.
* This is mainly used to handle upload with the board/port combination
* the monitor is listening to.
* @returns
*/
async pause(): Promise<void> {
return new Promise(async (resolve) => {
if (!this.duplex) {
this.logger.warn(
`monitor to ${this.port?.address} using ${this.port?.protocol} already stopped`
);
return resolve();
}
// It's enough to close the connection with the client
// to stop the monitor process
this.duplex.end();
this.logger.info(
`stopped monitor to ${this.port?.address} using ${this.port?.protocol}`
);
this.duplex.on('end', resolve);
});
}
/**
* Stop the monitor currently running
*/
async stop(): Promise<void> {
return this.pause().finally(this.stopMessagesHandlers.bind(this));
}
/**
* Send a message to the running monitor, a well behaved monitor
* will then send that message to the board.
* We MUST NEVER send a message that wasn't a user's input to the board.
* @param message string sent to running monitor
* @returns a status to verify message has been sent.
*/
async send(message: string): Promise<Status> {
if (!this.duplex) {
return Status.NOT_CONNECTED;
}
await this.coreClientProvider.initialized;
const coreClient = await this.coreClient();
const { instance } = coreClient;
const req = new MonitorRequest();
req.setInstance(instance);
req.setTxData(new TextEncoder().encode(message));
return new Promise<Status>((resolve) => {
if (this.duplex) {
this.duplex?.write(req, () => {
resolve(Status.OK);
});
return;
}
this.stop().then(() => resolve(Status.NOT_CONNECTED));
});
}
/**
*
* @returns map of current monitor settings
*/
currentSettings(): PluggableMonitorSettings {
return this.settings;
}
// TODO: move this into MonitoSettingsProvider
/**
* Returns the possible configurations used to connect a monitor
* to the board specified by fqbn using the specified protocol
* @param protocol the protocol of the monitor we want get settings for
* @param fqbn the fqbn of the board we want to monitor
* @returns a map of all the settings supported by the monitor
*/
private async portMonitorSettings(
protocol: string,
fqbn: string
): Promise<PluggableMonitorSettings> {
await this.coreClientProvider.initialized;
const coreClient = await this.coreClient();
const { client, instance } = coreClient;
const req = new EnumerateMonitorPortSettingsRequest();
req.setInstance(instance);
req.setPortProtocol(protocol);
req.setFqbn(fqbn);
const res = await new Promise<EnumerateMonitorPortSettingsResponse>(
(resolve, reject) => {
client.enumerateMonitorPortSettings(req, (err, resp) => {
if (!!err) {
reject(err);
}
resolve(resp);
});
}
);
const settings: PluggableMonitorSettings = {};
for (const iterator of res.getSettingsList()) {
settings[iterator.getSettingId()] = {
id: iterator.getSettingId(),
label: iterator.getLabel(),
type: iterator.getType(),
values: iterator.getEnumValuesList(),
selectedValue: iterator.getValue(),
};
}
return settings;
}
/**
* Set monitor settings, if there is a running monitor they'll be sent
* to it, otherwise they'll be used when starting one.
* Only values in settings parameter will be change, other values won't
* be changed in any way.
* @param settings map of monitor settings to change
* @returns a status to verify settings have been sent.
*/
async changeSettings(settings: PluggableMonitorSettings): Promise<Status> {
const config = new MonitorPortConfiguration();
for (const id in settings) {
const s = new MonitorPortSetting();
s.setSettingId(id);
s.setValue(settings[id].selectedValue);
config.addSettings(s);
this.settings[id] = settings[id];
}
if (!this.duplex) {
return Status.NOT_CONNECTED;
}
await this.coreClientProvider.initialized;
const coreClient = await this.coreClient();
const { instance } = coreClient;
const req = new MonitorRequest();
req.setInstance(instance);
req.setPortConfiguration(config);
this.duplex.write(req);
return Status.OK;
}
/**
* Starts the necessary handlers to send and receive
* messages to and from the frontend and the running monitor
*/
private startMessagesHandlers(): void {
if (!this.flushMessagesInterval) {
const flushMessagesToFrontend = () => {
if (this.messages.length) {
this.webSocketProvider.sendMessage(JSON.stringify(this.messages));
this.messages = [];
}
};
this.flushMessagesInterval = setInterval(flushMessagesToFrontend, 32);
}
if (!this.onMessageReceived) {
this.onMessageReceived = this.webSocketProvider.onMessageReceived(
(msg: string) => {
const message: Monitor.Message = JSON.parse(msg);
switch (message.command) {
case Monitor.Command.SEND_MESSAGE:
this.send(message.data);
break;
case Monitor.Command.CHANGE_SETTINGS:
const settings: PluggableMonitorSettings = JSON.parse(
message.data
);
this.changeSettings(settings);
break;
}
}
);
}
}
/**
* Stops the necessary handlers to send and receive messages to
* and from the frontend and the running monitor
*/
private stopMessagesHandlers(): void {
if (this.flushMessagesInterval) {
clearInterval(this.flushMessagesInterval);
this.flushMessagesInterval = undefined;
}
if (this.onMessageReceived) {
this.onMessageReceived.dispose();
this.onMessageReceived = undefined;
}
}
}
/**
* Splits a string into an array without removing newline char.
* @param s string to split into lines
* @returns an lines array
*/
function splitLines(s: string): string[] {
return s.split(/(?<=\n)/);
}

View File

@@ -0,0 +1,145 @@
import * as fs from 'fs';
import { join } from 'path';
import { injectable, inject, postConstruct } from 'inversify';
import { EnvVariablesServer } from '@theia/core/lib/common/env-variables';
import { FileUri } from '@theia/core/lib/node/file-uri';
import { promisify } from 'util';
import {
PluggableMonitorSettings,
MonitorSettingsProvider,
} from './monitor-settings-provider';
import { Deferred } from '@theia/core/lib/common/promise-util';
const MONITOR_SETTINGS_FILE = 'pluggable-monitor-settings.json';
@injectable()
export class MonitorSettingsProviderImpl implements MonitorSettingsProvider {
@inject(EnvVariablesServer)
protected readonly envVariablesServer: EnvVariablesServer;
protected ready = new Deferred<void>();
// this is populated with all settings coming from the CLI. This should never be modified
// // as it is used to double check the monitorSettings attribute
// private monitorDefaultSettings: PluggableMonitorSettings;
// this contains actual values coming from the stored file and edited by the user
// this is a map with MonitorId as key and PluggableMonitorSetting as value
private monitorSettings: Record<string, PluggableMonitorSettings>;
private pluggableMonitorSettingsPath: string;
@postConstruct()
protected async init(): Promise<void> {
// get the monitor settings file path
const configDirUri = await this.envVariablesServer.getConfigDirUri();
this.pluggableMonitorSettingsPath = join(
FileUri.fsPath(configDirUri),
MONITOR_SETTINGS_FILE
);
// read existing settings
await this.readFile();
console.log(this.monitorSettings);
this.ready.resolve();
}
async getSettings(
monitorId: string,
defaultSettings: PluggableMonitorSettings
): Promise<PluggableMonitorSettings> {
// wait for the service to complete the init
await this.ready.promise;
const { matchingSettings } = this.longestPrefixMatch(monitorId);
return this.reconcileSettings(matchingSettings, defaultSettings);
}
async setSettings(
monitorId: string,
settings: PluggableMonitorSettings
): Promise<PluggableMonitorSettings> {
// wait for the service to complete the init
await this.ready.promise;
const newSettings = this.reconcileSettings(
settings,
this.monitorSettings[monitorId]
);
this.monitorSettings[monitorId] = newSettings;
await this.writeFile();
return newSettings;
}
private reconcileSettings(
newSettings: PluggableMonitorSettings,
defaultSettings: PluggableMonitorSettings
): PluggableMonitorSettings {
// TODO: implement
return newSettings;
}
private async readFile(): Promise<void> {
const rawJson = await promisify(fs.readFile)(
this.pluggableMonitorSettingsPath,
{
encoding: 'utf-8',
flag: 'a+', // a+ = append and read, creating the file if it doesn't exist
}
);
if (!rawJson) {
this.monitorSettings = {};
}
try {
this.monitorSettings = JSON.parse(rawJson);
} catch (error) {
console.error(
'Could not parse the pluggable monitor settings file. Using empty file.'
);
this.monitorSettings = {};
}
}
private async writeFile() {
await promisify(fs.writeFile)(
this.pluggableMonitorSettingsPath,
JSON.stringify(this.monitorSettings)
);
}
private longestPrefixMatch(id: string): {
matchingPrefix: string;
matchingSettings: PluggableMonitorSettings;
} {
const separator = '-';
const idTokens = id.split(separator);
let matchingPrefix = '';
let matchingSettings: PluggableMonitorSettings = {};
const monitorSettingsKeys = Object.keys(this.monitorSettings);
for (let i = 0; i < idTokens.length; i++) {
const prefix = idTokens.slice(0, i + 1).join(separator);
for (let k = 0; k < monitorSettingsKeys.length; k++) {
if (monitorSettingsKeys[k].startsWith(prefix)) {
matchingPrefix = prefix;
matchingSettings = this.monitorSettings[monitorSettingsKeys[k]];
break;
}
}
if (matchingPrefix.length) {
break;
}
}
return { matchingPrefix, matchingSettings };
}
}

View File

@@ -0,0 +1,20 @@
import { MonitorModel } from '../../browser/monitor-model';
import { PluggableMonitorSetting } from '../../common/protocol';
export type PluggableMonitorSettings = Record<string, PluggableMonitorSetting>;
export interface MonitorSettings {
pluggableMonitorSettings?: PluggableMonitorSettings;
monitorUISettings?: Partial<MonitorModel.State>;
}
export const MonitorSettingsProvider = Symbol('MonitorSettingsProvider');
export interface MonitorSettingsProvider {
getSettings(
monitorId: string,
defaultSettings: PluggableMonitorSettings
): Promise<PluggableMonitorSettings>;
setSettings(
monitorId: string,
settings: PluggableMonitorSettings
): Promise<PluggableMonitorSettings>;
}

View File

@@ -1,26 +0,0 @@
import * as grpc from '@grpc/grpc-js';
import { injectable } from 'inversify';
import { MonitorServiceClient } from '../cli-protocol/cc/arduino/cli/monitor/v1/monitor_grpc_pb';
import * as monitorGrpcPb from '../cli-protocol/cc/arduino/cli/monitor/v1/monitor_grpc_pb';
import { GrpcClientProvider } from '../grpc-client-provider';
@injectable()
export class MonitorClientProvider extends GrpcClientProvider<MonitorServiceClient> {
createClient(port: string | number): MonitorServiceClient {
// https://github.com/agreatfool/grpc_tools_node_protoc_ts/blob/master/doc/grpcjs_support.md#usage
const MonitorServiceClient = grpc.makeClientConstructor(
// @ts-expect-error: ignore
monitorGrpcPb['cc.arduino.cli.monitor.v1.MonitorService'],
'MonitorServiceService'
) as any;
return new MonitorServiceClient(
`localhost:${port}`,
grpc.credentials.createInsecure(),
this.channelOptions
);
}
close(client: MonitorServiceClient): void {
client.close();
}
}

View File

@@ -1,397 +0,0 @@
import { ClientDuplexStream } from '@grpc/grpc-js';
import { TextEncoder } from 'util';
import { injectable, inject, named } from 'inversify';
import { Struct } from 'google-protobuf/google/protobuf/struct_pb';
import { ILogger } from '@theia/core/lib/common/logger';
import {
SerialService,
SerialServiceClient,
SerialConfig,
SerialError,
Status,
} from '../../common/protocol/serial-service';
import {
StreamingOpenRequest,
StreamingOpenResponse,
MonitorConfig as GrpcMonitorConfig,
} from '../cli-protocol/cc/arduino/cli/monitor/v1/monitor_pb';
import { MonitorClientProvider } from './monitor-client-provider';
import { Board } from '../../common/protocol/boards-service';
import { WebSocketService } from '../web-socket/web-socket-service';
import { SerialPlotter } from '../../browser/serial/plotter/protocol';
import { Disposable } from '@theia/core/shared/vscode-languageserver-protocol';
export const SerialServiceName = 'serial-service';
interface ErrorWithCode extends Error {
readonly code: number;
}
namespace ErrorWithCode {
export function toSerialError(
error: Error,
config: SerialConfig
): SerialError {
const { message } = error;
let code = undefined;
if (is(error)) {
// TODO: const `mapping`. Use regex for the `message`.
const mapping = new Map<string, number>();
mapping.set(
'1 CANCELLED: Cancelled on client',
SerialError.ErrorCodes.CLIENT_CANCEL
);
mapping.set(
'2 UNKNOWN: device not configured',
SerialError.ErrorCodes.DEVICE_NOT_CONFIGURED
);
mapping.set(
'2 UNKNOWN: error opening serial connection: Serial port busy',
SerialError.ErrorCodes.DEVICE_BUSY
);
code = mapping.get(message);
}
return {
message,
code,
config,
};
}
function is(error: Error & { code?: number }): error is ErrorWithCode {
return typeof error.code === 'number';
}
}
@injectable()
export class SerialServiceImpl implements SerialService {
protected theiaFEClient?: SerialServiceClient;
protected serialConfig?: SerialConfig;
protected serialConnection?: {
duplex: ClientDuplexStream<StreamingOpenRequest, StreamingOpenResponse>;
config: SerialConfig;
};
protected messages: string[] = [];
protected onMessageReceived: Disposable | null;
protected onWSClientsNumberChanged: Disposable | null;
protected flushMessagesInterval: NodeJS.Timeout | null;
uploadInProgress = false;
constructor(
@inject(ILogger)
@named(SerialServiceName)
protected readonly logger: ILogger,
@inject(MonitorClientProvider)
protected readonly serialClientProvider: MonitorClientProvider,
@inject(WebSocketService)
protected readonly webSocketService: WebSocketService
) { }
async isSerialPortOpen(): Promise<boolean> {
return !!this.serialConnection;
}
setClient(client: SerialServiceClient | undefined): void {
this.theiaFEClient = client;
this.theiaFEClient?.notifyWebSocketChanged(
this.webSocketService.getAddress().port
);
// listen for the number of websocket clients and create or dispose the serial connection
this.onWSClientsNumberChanged =
this.webSocketService.onClientsNumberChanged(async () => {
await this.connectSerialIfRequired();
});
}
public async clientsAttached(): Promise<number> {
return this.webSocketService.getConnectedClientsNumber.bind(
this.webSocketService
)();
}
public async connectSerialIfRequired(): Promise<void> {
if (this.uploadInProgress) return;
const clients = await this.clientsAttached();
clients > 0 ? await this.connect() : await this.disconnect();
}
dispose(): void {
this.logger.info('>>> Disposing serial service...');
if (this.serialConnection) {
this.disconnect();
}
this.logger.info('<<< Disposed serial service.');
this.theiaFEClient = undefined;
}
async setSerialConfig(config: SerialConfig): Promise<void> {
this.serialConfig = config;
await this.disconnect();
await this.connectSerialIfRequired();
}
async updateWsConfigParam(
config: Partial<SerialPlotter.Config>
): Promise<void> {
const msg: SerialPlotter.Protocol.Message = {
command: SerialPlotter.Protocol.Command.MIDDLEWARE_CONFIG_CHANGED,
data: config,
};
this.webSocketService.sendMessage(JSON.stringify(msg));
}
private async connect(): Promise<Status> {
if (!this.serialConfig) {
return Status.CONFIG_MISSING;
}
this.logger.info(
`>>> Creating serial connection for ${Board.toString(
this.serialConfig.board
)} on port ${this.serialConfig.port.address}...`
);
if (this.serialConnection) {
return Status.ALREADY_CONNECTED;
}
const client = await this.serialClientProvider.client();
if (!client) {
return Status.NOT_CONNECTED;
}
if (client instanceof Error) {
return { message: client.message };
}
const duplex = client.streamingOpen();
this.serialConnection = { duplex, config: this.serialConfig };
const serialConfig = this.serialConfig;
duplex.on(
'error',
((error: Error) => {
const serialError = ErrorWithCode.toSerialError(error, serialConfig);
if (serialError.code !== SerialError.ErrorCodes.CLIENT_CANCEL) {
this.disconnect(serialError).then(() => {
if (this.theiaFEClient) {
this.theiaFEClient.notifyError(serialError);
}
});
}
if (serialError.code === undefined) {
// Log the original, unexpected error.
this.logger.error(error);
}
}).bind(this)
);
this.updateWsConfigParam({ connected: !!this.serialConnection });
const flushMessagesToFrontend = () => {
if (this.messages.length) {
this.webSocketService.sendMessage(JSON.stringify(this.messages));
this.messages = [];
}
};
this.onMessageReceived = this.webSocketService.onMessageReceived(
(msg: string) => {
try {
const message: SerialPlotter.Protocol.Message = JSON.parse(msg);
switch (message.command) {
case SerialPlotter.Protocol.Command.PLOTTER_SEND_MESSAGE:
this.sendMessageToSerial(message.data);
break;
case SerialPlotter.Protocol.Command.PLOTTER_SET_BAUDRATE:
this.theiaFEClient?.notifyBaudRateChanged(
parseInt(message.data, 10) as SerialConfig.BaudRate
);
break;
case SerialPlotter.Protocol.Command.PLOTTER_SET_LINE_ENDING:
this.theiaFEClient?.notifyLineEndingChanged(message.data);
break;
case SerialPlotter.Protocol.Command.PLOTTER_SET_INTERPOLATE:
this.theiaFEClient?.notifyInterpolateChanged(message.data);
break;
default:
break;
}
} catch (error) { }
}
);
// empty the queue every 32ms (~30fps)
this.flushMessagesInterval = setInterval(flushMessagesToFrontend, 32);
duplex.on(
'data',
((resp: StreamingOpenResponse) => {
const raw = resp.getData();
const message =
typeof raw === 'string' ? raw : new TextDecoder('utf8').decode(raw);
// split the message if it contains more lines
const messages = stringToArray(message);
this.messages.push(...messages);
}).bind(this)
);
const { type, port } = this.serialConfig;
const req = new StreamingOpenRequest();
const monitorConfig = new GrpcMonitorConfig();
monitorConfig.setType(this.mapType(type));
monitorConfig.setTarget(port.address);
if (this.serialConfig.baudRate !== undefined) {
monitorConfig.setAdditionalConfig(
Struct.fromJavaScript({ BaudRate: this.serialConfig.baudRate })
);
}
req.setConfig(monitorConfig);
if (!this.serialConnection) {
return await this.disconnect();
}
const writeTimeout = new Promise<Status>((resolve) => {
setTimeout(async () => {
resolve(Status.NOT_CONNECTED);
}, 1000);
});
const writePromise = (serialConnection: any) => {
return new Promise<Status>((resolve) => {
serialConnection.duplex.write(req, () => {
const boardName = this.serialConfig?.board
? Board.toString(this.serialConfig.board, {
useFqbn: false,
})
: 'unknown board';
const portName = this.serialConfig?.port
? this.serialConfig.port.address
: 'unknown port';
this.logger.info(
`<<< Serial connection created for ${boardName} on port ${portName}.`
);
resolve(Status.OK);
});
});
};
const status = await Promise.race([
writeTimeout,
writePromise(this.serialConnection),
]);
if (status === Status.NOT_CONNECTED) {
this.disconnect();
}
return status;
}
public async disconnect(reason?: SerialError): Promise<Status> {
return new Promise<Status>((resolve) => {
try {
if (this.onMessageReceived) {
this.onMessageReceived.dispose();
this.onMessageReceived = null;
}
if (this.flushMessagesInterval) {
clearInterval(this.flushMessagesInterval);
this.flushMessagesInterval = null;
}
if (
!this.serialConnection &&
reason &&
reason.code === SerialError.ErrorCodes.CLIENT_CANCEL
) {
resolve(Status.OK);
return;
}
this.logger.info('>>> Disposing serial connection...');
if (!this.serialConnection) {
this.logger.warn('<<< Not connected. Nothing to dispose.');
resolve(Status.NOT_CONNECTED);
return;
}
const { duplex, config } = this.serialConnection;
this.logger.info(
`<<< Disposed serial connection for ${Board.toString(config.board, {
useFqbn: false,
})} on port ${config.port.address}.`
);
duplex.cancel();
} finally {
this.serialConnection = undefined;
this.updateWsConfigParam({ connected: !!this.serialConnection });
this.messages.length = 0;
setTimeout(() => {
resolve(Status.OK);
}, 200);
}
});
}
async sendMessageToSerial(message: string): Promise<Status> {
if (!this.serialConnection) {
return Status.NOT_CONNECTED;
}
const req = new StreamingOpenRequest();
req.setData(new TextEncoder().encode(message));
return new Promise<Status>((resolve) => {
if (this.serialConnection) {
this.serialConnection.duplex.write(req, () => {
resolve(Status.OK);
});
return;
}
this.disconnect().then(() => resolve(Status.NOT_CONNECTED));
});
}
protected mapType(
type?: SerialConfig.ConnectionType
): GrpcMonitorConfig.TargetType {
switch (type) {
case SerialConfig.ConnectionType.SERIAL:
return GrpcMonitorConfig.TargetType.TARGET_TYPE_SERIAL;
default:
return GrpcMonitorConfig.TargetType.TARGET_TYPE_SERIAL;
}
}
}
// converts 'ab\nc\nd' => [ab\n,c\n,d]
function stringToArray(string: string, separator = '\n') {
const retArray: string[] = [];
let prevChar = separator;
for (let i = 0; i < string.length; i++) {
const currChar = string[i];
if (prevChar === separator) {
retArray.push(currChar);
} else {
const lastWord = retArray[retArray.length - 1];
retArray[retArray.length - 1] = lastWord + currChar;
}
prevChar = currChar;
}
return retArray;
}

View File

@@ -1,10 +1,10 @@
import { Emitter } from '@theia/core'; import { Emitter } from '@theia/core';
import { injectable } from 'inversify'; import { injectable } from '@theia/core/shared/inversify';
import * as WebSocket from 'ws'; import * as WebSocket from 'ws';
import { WebSocketService } from './web-socket-service'; import { WebSocketProvider } from './web-socket-provider';
@injectable() @injectable()
export default class WebSocketServiceImpl implements WebSocketService { export default class WebSocketProviderImpl implements WebSocketProvider {
protected wsClients: WebSocket[]; protected wsClients: WebSocket[];
protected server: WebSocket.Server; protected server: WebSocket.Server;

View File

@@ -1,8 +1,8 @@
import { Event } from '@theia/core/lib/common/event'; import { Event } from '@theia/core/lib/common/event';
import * as WebSocket from 'ws'; import * as WebSocket from 'ws';
export const WebSocketService = Symbol('WebSocketService'); export const WebSocketProvider = Symbol('WebSocketProvider');
export interface WebSocketService { export interface WebSocketProvider {
getAddress(): WebSocket.AddressInfo; getAddress(): WebSocket.AddressInfo;
sendMessage(message: string): void; sendMessage(message: string): void;
onMessageReceived: Event<string>; onMessageReceived: Event<string>;

View File

@@ -1,22 +0,0 @@
import { SerialConfig } from '../../../common/protocol/serial-service';
import { aBoard, anotherBoard, anotherPort, aPort } from './boards';
export const aSerialConfig: SerialConfig = {
board: aBoard,
port: aPort,
baudRate: 9600,
};
export const anotherSerialConfig: SerialConfig = {
board: anotherBoard,
port: anotherPort,
baudRate: 9600,
};
export class WebSocketMock {
readonly url: string;
constructor(url: string) {
this.url = url;
}
close() {}
}

View File

@@ -1,167 +0,0 @@
import { SerialServiceImpl } from './../../node/serial/serial-service-impl';
import { IMock, It, Mock } from 'typemoq';
import { createSandbox } from 'sinon';
import * as sinonChai from 'sinon-chai';
import { expect, use } from 'chai';
use(sinonChai);
import { ILogger } from '@theia/core/lib/common/logger';
import { MonitorClientProvider } from '../../node/serial/monitor-client-provider';
import { WebSocketService } from '../../node/web-socket/web-socket-service';
import { MonitorServiceClient } from '../../node/cli-protocol/cc/arduino/cli/monitor/v1/monitor_grpc_pb';
import { Status } from '../../common/protocol';
describe('SerialServiceImpl', () => {
let subject: SerialServiceImpl;
let logger: IMock<ILogger>;
let serialClientProvider: IMock<MonitorClientProvider>;
let webSocketService: IMock<WebSocketService>;
beforeEach(() => {
logger = Mock.ofType<ILogger>();
logger.setup((b) => b.info(It.isAnyString()));
logger.setup((b) => b.warn(It.isAnyString()));
logger.setup((b) => b.error(It.isAnyString()));
serialClientProvider = Mock.ofType<MonitorClientProvider>();
webSocketService = Mock.ofType<WebSocketService>();
subject = new SerialServiceImpl(
logger.object,
serialClientProvider.object,
webSocketService.object
);
});
context('when a serial connection is requested', () => {
const sandbox = createSandbox();
beforeEach(() => {
subject.uploadInProgress = false;
sandbox.spy(subject, 'disconnect');
sandbox.spy(subject, 'updateWsConfigParam');
});
afterEach(function () {
sandbox.restore();
});
context('and an upload is in progress', () => {
beforeEach(async () => {
subject.uploadInProgress = true;
});
it('should not change the connection status', async () => {
await subject.connectSerialIfRequired();
expect(subject.disconnect).to.have.callCount(0);
});
});
context('and there is no upload in progress', () => {
beforeEach(async () => {
subject.uploadInProgress = false;
});
context('and there are 0 attached ws clients', () => {
it('should disconnect', async () => {
await subject.connectSerialIfRequired();
expect(subject.disconnect).to.have.been.calledOnce;
});
});
context('and there are > 0 attached ws clients', () => {
beforeEach(() => {
webSocketService
.setup((b) => b.getConnectedClientsNumber())
.returns(() => 1);
});
it('should not call the disconenct', async () => {
await subject.connectSerialIfRequired();
expect(subject.disconnect).to.have.callCount(0);
});
});
});
});
context('when a disconnection is requested', () => {
const sandbox = createSandbox();
beforeEach(() => { });
afterEach(function () {
sandbox.restore();
});
context('and a serialConnection is not set', () => {
it('should return a NOT_CONNECTED status', async () => {
const status = await subject.disconnect();
expect(status).to.be.equal(Status.NOT_CONNECTED);
});
});
context('and a serialConnection is set', async () => {
beforeEach(async () => {
sandbox.spy(subject, 'updateWsConfigParam');
await subject.disconnect();
});
it('should dispose the serialConnection', async () => {
const serialConnectionOpen = await subject.isSerialPortOpen();
expect(serialConnectionOpen).to.be.false;
});
it('should call updateWsConfigParam with disconnected status', async () => {
expect(subject.updateWsConfigParam).to.be.calledWith({
connected: false,
});
});
});
});
context('when a new config is passed in', () => {
const sandbox = createSandbox();
beforeEach(async () => {
subject.uploadInProgress = false;
webSocketService
.setup((b) => b.getConnectedClientsNumber())
.returns(() => 1);
serialClientProvider
.setup((b) => b.client())
.returns(async () => {
return {
streamingOpen: () => {
return {
on: (str: string, cb: any) => { },
write: (chunk: any, cb: any) => {
cb();
},
cancel: () => { },
};
},
} as MonitorServiceClient;
});
sandbox.spy(subject, 'disconnect');
await subject.setSerialConfig({
board: { name: 'test' },
port: { id: 'test|test', address: 'test', addressLabel: 'test', protocol: 'test', protocolLabel: 'test' },
});
});
afterEach(function () {
sandbox.restore();
subject.dispose();
});
it('should disconnect from previous connection', async () => {
expect(subject.disconnect).to.be.called;
});
it('should create the serialConnection', async () => {
const serialConnectionOpen = await subject.isSerialPortOpen();
expect(serialConnectionOpen).to.be.true;
});
});
});

View File

@@ -23,8 +23,8 @@
"downloadingNotice": "Downloading the latest version of the Arduino IDE.", "downloadingNotice": "Downloading the latest version of the Arduino IDE.",
"updateAvailable": "Update Available", "updateAvailable": "Update Available",
"newVersionAvailable": "A new version of Arduino IDE ({0}) is available for download.", "newVersionAvailable": "A new version of Arduino IDE ({0}) is available for download.",
"skipVersionButton": "Skip Version", "skipVersionButton": "Volgende Weergawe",
"downloadButton": "Download", "downloadButton": "Aflaai",
"goToDownloadPage": "An update for the Arduino IDE is available, but we're not able to download and install it automatically. Please go to the download page and download the latest version from there.", "goToDownloadPage": "An update for the Arduino IDE is available, but we're not able to download and install it automatically. Please go to the download page and download the latest version from there.",
"goToDownloadButton": "Go To Download", "goToDownloadButton": "Go To Download",
"ideUpdaterDialog": "Software Update", "ideUpdaterDialog": "Software Update",
@@ -107,11 +107,11 @@
"continue": "Continue", "continue": "Continue",
"pushSketch": "Push Sketch", "pushSketch": "Push Sketch",
"pushSketchMsg": "This is a Public Sketch. Before pushing, make sure any sensitive information is defined in arduino_secrets.h files. You can make a Sketch private from the Share panel.", "pushSketchMsg": "This is a Public Sketch. Before pushing, make sure any sensitive information is defined in arduino_secrets.h files. You can make a Sketch private from the Share panel.",
"pull": "Pull", "pull": "Trek",
"pullSketchMsg": "Pulling this Sketch from the Cloud will overwrite its local version. Are you sure you want to continue?", "pullSketchMsg": "Pulling this Sketch from the Cloud will overwrite its local version. Are you sure you want to continue?",
"donePulling": "Done pulling {0}.", "donePulling": "Done pulling {0}.",
"notYetPulled": "Cannot push to Cloud. It is not yet pulled.", "notYetPulled": "Cannot push to Cloud. It is not yet pulled.",
"push": "Push", "push": "Stoot",
"pullFirst": "You have to pull first to be able to push to the Cloud.", "pullFirst": "You have to pull first to be able to push to the Cloud.",
"donePushing": "Done pushing {0}.", "donePushing": "Done pushing {0}.",
"connected": "Connected", "connected": "Connected",
@@ -131,7 +131,7 @@
"succesfullyUninstalledPlatform": "Successfully uninstalled platform {0}:{1}", "succesfullyUninstalledPlatform": "Successfully uninstalled platform {0}:{1}",
"couldNotFindPreviouslySelected": "Could not find previously selected board '{0}' in installed platform '{1}'. Please manually reselect the board you want to use. Do you want to reselect it now?", "couldNotFindPreviouslySelected": "Could not find previously selected board '{0}' in installed platform '{1}'. Please manually reselect the board you want to use. Do you want to reselect it now?",
"reselectLater": "Herselekteer later", "reselectLater": "Herselekteer later",
"noneSelected": "No boards selected.", "noneSelected": "Geen bord gekies nie.",
"noPortsSelected": "No ports selected for board: '{0}'.", "noPortsSelected": "No ports selected for board: '{0}'.",
"noFQBN": "The FQBN is not available for the selected board \"{0}\". Do you have the corresponding core installed?", "noFQBN": "The FQBN is not available for the selected board \"{0}\". Do you have the corresponding core installed?",
"openBoardsConfig": "Kies ander bord en poort...", "openBoardsConfig": "Kies ander bord en poort...",

View File

@@ -1,330 +1,330 @@
{ {
"arduino": { "arduino": {
"common": { "common": {
"offlineIndicator": "You appear to be offline. Without an Internet connection, the Arduino CLI might not be able to download the required resources and could cause malfunction. Please connect to the Internet and restart the application.", "offlineIndicator": "انت غير متصل بالانترنت على الارجح , بدون الاتصال بالانترنت لن تستطيع واجهة سطر الاوامر الخاصة بالاردوينو \"Arduino CLI\" تحميل الموارد المطلوبة و من الممكن ان تسبب باخطاء , الرجاء الاتصال بالانترنت و اعادة تشغيل البرنامج",
"noBoardSelected": "No board selected", "noBoardSelected": "لم يتم اختيار اي لوحة",
"selectedOn": "on {0}", "selectedOn": "{0} شغّل",
"notConnected": "[not connected]", "notConnected": "[غير متصل]",
"serialMonitor": "مراقب المنفذ التسلسلي \"سيريال بورت\"\n ", "serialMonitor": "مراقب المنفذ التسلسلي \"سيريال بورت\"\n ",
"oldFormat": "The '{0}' still uses the old `.pde` format. Do you want to switch to the new `.ino` extension?", "oldFormat": "ال '{0}' ما زالت تستخدم صيغة `.pde` القديمة . هل تريد الانتقال الى صيغة `.ino`  الجديدة ؟",
"later": "Later", "later": "لاحقا",
"selectBoard": "Select Board", "selectBoard": "اختر لوحة",
"unknown": "Unknown", "unknown": "غير معروف",
"processing": "Processing", "processing": "تتم المعالجة",
"saveChangesToSketch": "Do you want to save changes to this sketch before closing?", "saveChangesToSketch": "هل تريد حفظ التغييرات على هذا الملف قبل الخروج ؟",
"loseChanges": "If you don't save, your changes will be lost." "loseChanges": "اذا لم تقم بالحفظ ستزول كل التغييرات التي قمت بها "
}, },
"ide-updater": { "ide-updater": {
"errorCheckingForUpdates": "Error while checking for Arduino IDE updates.\n{0}", "errorCheckingForUpdates": "حدث خطأ اثناء البحث عن تحديثات للـ Arduino IDE \n{0}",
"notNowButton": "Not now", "notNowButton": "ليس الان",
"versionDownloaded": "Arduino IDE {0} has been downloaded.", "versionDownloaded": "لقد تم تحميل {0} Arduino IDE",
"closeToInstallNotice": "Close the software and install the update on your machine.", "closeToInstallNotice": "اغلق البرمجية و حّدث الجهاز الخاص بك ",
"closeAndInstallButton": "Close and Install", "closeAndInstallButton": "قم بالاغلاق و التحديث",
"downloadingNotice": "Downloading the latest version of the Arduino IDE.", "downloadingNotice": "يتم تحميل اخر نسخة من Arduino IDE",
"updateAvailable": "Update Available", "updateAvailable": "يوجد تحديث",
"newVersionAvailable": "A new version of Arduino IDE ({0}) is available for download.", "newVersionAvailable": "نسخة جديدة من {0} Arduino IDE قابلة للتحميل",
"skipVersionButton": "Skip Version", "skipVersionButton": "تخطى النسخة",
"downloadButton": "Download", "downloadButton": "حمّل",
"goToDownloadPage": "An update for the Arduino IDE is available, but we're not able to download and install it automatically. Please go to the download page and download the latest version from there.", "goToDownloadPage": "يوجد تحديث للArduino IDE . لكننا غير قادرين على تنزيله و تثبيته تلقائيا . الرجاء الذهاب الى صفحة التحميلات و تنزيل احدث نسخة من هناك.",
"goToDownloadButton": "Go To Download", "goToDownloadButton": "اذهب الى التحميلات",
"ideUpdaterDialog": "Software Update", "ideUpdaterDialog": "التحديثات للبرنامج",
"noUpdatesAvailable": "There are no recent updates available for the Arduino IDE" "noUpdatesAvailable": "لا يوجد تحديثات اخيرة متوافرة لل Arduino IDE"
}, },
"menu": { "menu": {
"sketch": "Sketch", "sketch": "مشروع",
"tools": "ادوات" "tools": "ادوات"
}, },
"debug": { "debug": {
"optimizeForDebugging": "Optimize for Debugging", "optimizeForDebugging": "التحسين من اجل التصحيح البرمجي",
"debugWithMessage": "Debug - {0}", "debugWithMessage": "تصحيح برمجي - {0}",
"noPlatformInstalledFor": "Platform is not installed for '{0}'", "noPlatformInstalledFor": "المنصة غير مثبتة ل '{0}'",
"debuggingNotSupported": "Debugging is not supported by '{0}'" "debuggingNotSupported": "'{0}' لا يقبل التصحيح البرمجي"
}, },
"preferences": { "preferences": {
"language.log": "True if the Arduino Language Server should generate log files into the sketch folder. Otherwise, false. It's false by default.", "language.log": "\"True\" اذا كان مخدم اللغات الخاص بArduino يستطيع توليد سجلات الى ملف المشروع , و الا \"False\", و هي كذلك بشكل افتراضي.",
"compile.verbose": "True for verbose compile output. False by default", "compile.verbose": "True لخرج الترجمة المطول . False افتراضيا",
"compile.warnings": "Tells gcc which warning level to use. It's 'None' by default", "compile.warnings": "يخبر gcc اي مستوى انذار سيتم استخدامه , قيمته 'None' افتراضيا",
"upload.verbose": "True for verbose upload output. False by default.", "upload.verbose": "True لخرج الرفع المطول . False افتراضيا",
"window.autoScale": "True if the user interface automatically scales with the font size.", "window.autoScale": "True اذا كان مقياس الواجهة يتزامن تلقائيا مع حجم الخط ",
"window.zoomLevel": "Adjust the zoom level of the window. The original size is 0 and each increment above (e.g. 1) or below (e.g. -1) represents zooming 20% larger or smaller. You can also enter decimals to adjust the zoom level with a finer granularity.", "window.zoomLevel": "تعديل درجة التكبير للنافذة . الحجم الاصلي 0 و كل زيادة فوقه (مثلا 1) او اقل (مثلا -1) تمثل تكبير بدرجة 20% اكبر او اصغر . تستطيع ايضا ادخال فواصل لتعديل درجة التكبير بدقة اكبر",
"ide.updateChannel": "Release channel to get updated from. 'stable' is the stable release, 'nightly' is the latest development build.", "ide.updateChannel": "انشر القناة للحصول على تحديثات من . 'stable' هو النسخة الثابتة .'nightly' هي اخر نسخة تطويرية ",
"board.certificates": "List of certificates that can be uploaded to boards", "board.certificates": "قائمة الشهادات التي يمكن رفعها الى اللوحات",
"sketchbook.showAllFiles": "True to show all sketch files inside the sketch. It is false by default.", "sketchbook.showAllFiles": "True لعرض كل مجلدات مشاريع داخل المشروع . False افتراضيا",
"cloud.enabled": "True if the sketch sync functions are enabled. Defaults to true.", "cloud.enabled": "True اذا كانت مهام المزامنة مفعلة . True افتراضيا",
"cloud.pull.warn": "True if users should be warned before pulling a cloud sketch. Defaults to true.", "cloud.pull.warn": "True اذا كان يجب تحذير المستخدمين قبل سحب مشروع من السحابة . True افتراضيا",
"cloud.push.warn": "True if users should be warned before pushing a cloud sketch. Defaults to true.", "cloud.push.warn": "True اذا كان يجب تحذير المستخدمين قبل دفع مشروع الى السحابة . True افتراضيا",
"cloud.pushpublic.warn": "True if users should be warned before pushing a public sketch to the cloud. Defaults to true.", "cloud.pushpublic.warn": "True اذا كان يجب تحذير المستخدمين قبل دفع مشروع عام الى السحابة . True افتراضيا",
"cloud.sketchSyncEnpoint": "The endpoint used to push and pull sketches from a backend. By default it points to Arduino Cloud API.", "cloud.sketchSyncEnpoint": "الوجهة المستخدمة لدفع و سحب المشاريع من الخلفية . تشير افتراضيا الى Arduino Cloud API.",
"auth.clientID": "The OAuth2 client ID.", "auth.clientID": "ID الخاص بعميل OAuth2",
"auth.domain": "The OAuth2 domain.", "auth.domain": "نطاق OAuth2",
"auth.audience": "The OAuth2 audience.", "auth.audience": "جمهور OAuth2",
"auth.registerUri": "The URI used to register a new user.", "auth.registerUri": "عنوان URL المستخدم لتسجيل مستخدم جديد",
"network": "شبكة", "network": "شبكة",
"sketchbook.location": "Sketchbook location", "sketchbook.location": "موقع ملف المشاريع",
"browse": "استعرض", "browse": "استعرض",
"files.inside.sketches": "Show files inside Sketches", "files.inside.sketches": "اظهر الملفات داخل المشاريع",
"editorFontSize": "Editor font size", "editorFontSize": "حجم خط المحرّر",
"interfaceScale": "Interface scale", "interfaceScale": "مقياس الواجهة",
"showVerbose": "Show verbose output during", "showVerbose": "اظهر خرج مطوّل خلال",
"compilerWarnings": "Compiler warnings", "compilerWarnings": "تحذيرات المترجم",
"automatic": "تلقائي", "automatic": "تلقائي",
"compile": "compile", "compile": "الترجمة",
"upload": "upload", "upload": "الرفع",
"verifyAfterUpload": "Verify code after upload", "verifyAfterUpload": "التحقق من الكود بعد الرفع",
"editorQuickSuggestions": "Editor Quick Suggestions", "editorQuickSuggestions": "اقتراحات المحرّر السريعة",
"additionalManagerURLs": "تدبير عناوين اللوحات الإضافية", "additionalManagerURLs": "مدير اللوحات الاضافية",
"noProxy": "No proxy", "noProxy": "لا يوجد وكيل",
"manualProxy": "Manual proxy configuration", "manualProxy": "اعدادات الوكيل يدوياً",
"newSketchbookLocation": "Select new sketchbook location", "newSketchbookLocation": "اختر مكان المشروع الجديد",
"choose": "Choose", "choose": "اختر",
"enterAdditionalURLs": "Enter additional URLs, one for each row", "enterAdditionalURLs": "قم بادخال عناوين URL الاضافية , واحد لكل صف",
"unofficialBoardSupport": "Click for a list of unofficial board support URLs", "unofficialBoardSupport": "انقر لعرض قائمة عناوين URL للوحات المدعومة بشكل غير رسمي",
"invalid.sketchbook.location": "Invalid sketchbook location: {0}", "invalid.sketchbook.location": "موقع ملف المشروع غير صالح : {0}",
"invalid.editorFontSize": "Invalid editor font size. It must be a positive integer.", "invalid.editorFontSize": "حجم خط المحرّر غير صالح . يجب ان يكون عدد موجب",
"invalid.theme": "Invalid theme." "invalid.theme": "سمة غير صالحة"
}, },
"cloud": { "cloud": {
"signIn": "SIGN IN", "signIn": "تسجيل الدخول",
"signOut": "Sign Out", "signOut": "تسجيل الخروج",
"chooseSketchVisibility": "Choose visibility of your Sketch:", "chooseSketchVisibility": "اختر خصوصية مشروعك:",
"privateVisibility": "Private. Only you can view the Sketch.", "privateVisibility": "خاص . وحدك فقط من يستطيع رؤية المشروع",
"publicVisibility": "Public. Anyone with the link can view the Sketch.", "publicVisibility": "عام. اي شخص معه الرابط يستطيع رؤية المشروع",
"link": "Link:", "link": "الرابط:",
"embed": "Embed:", "embed": "تضمين:",
"cloudSketchbook": "Cloud Sketchbook", "cloudSketchbook": "مشاريع على السحابة",
"shareSketch": "Share Sketch", "shareSketch": "مشاركة المشروع",
"showHideRemoveSketchbook": "Show/Hide Remote Sketchbook", "showHideRemoveSketchbook": "اظهار/اخفاء المشاريع عن بعد",
"pullSketch": "Pull Sketch", "pullSketch": "سحب المشروع",
"openInCloudEditor": "Open in Cloud Editor", "openInCloudEditor": "الفتح في المحرّر السحابي",
"options": "Options...", "options": "اعدادات...",
"share": "Share...", "share": "مشاركة...",
"remote": "Remote", "remote": "عن بعد",
"emptySketchbook": "Your Sketchbook is empty", "emptySketchbook": "ملف المشاريع الخاص بك فارغ",
"visitArduinoCloud": "Visit Arduino Cloud to create Cloud Sketches.", "visitArduinoCloud": "قم بزيارة Arduino Cloud من اجل انشاء ملف مشاريع على السحابة",
"signInToCloud": "Sign in to Arduino Cloud", "signInToCloud": "تسجيل الدخول الى Arduino Cloud",
"syncEditSketches": "Sync and edit your Arduino Cloud Sketches", "syncEditSketches": "المزامنة و التعديل على مشاريعك في Arduino Cloud",
"learnMore": "Learn more", "learnMore": "تعرف على المزيد",
"continue": "Continue", "continue": "استئناف",
"pushSketch": "Push Sketch", "pushSketch": "دفع المشروع",
"pushSketchMsg": "This is a Public Sketch. Before pushing, make sure any sensitive information is defined in arduino_secrets.h files. You can make a Sketch private from the Share panel.", "pushSketchMsg": "هذا مشروع عام . قبل دفعه , تاكد من عدم وجود اي معلومات حساسة داخل ملف arduino_secrets.h . تستطيع جعل المشروع خاصا من لوحة المشاركة",
"pull": "Pull", "pull": "اسحب",
"pullSketchMsg": "Pulling this Sketch from the Cloud will overwrite its local version. Are you sure you want to continue?", "pullSketchMsg": "سحب هذا المشروع من Cloud سيقوم بالكتابة فوق النسخة المحلية . هل تريد الاكمال ؟",
"donePulling": "Done pulling {0}.", "donePulling": "تم السحب بنجاح '{0}'",
"notYetPulled": "Cannot push to Cloud. It is not yet pulled.", "notYetPulled": "تعذر الدفع الى Cloud . انها لم تسحب الى الان",
"push": "Push", "push": "ادفع",
"pullFirst": "You have to pull first to be able to push to the Cloud.", "pullFirst": "عليك السحب اولا لكي تصبح قادرا على الدفع الى السحابة",
"donePushing": "Done pushing {0}.", "donePushing": "تم الدفع بنجاح '{0}'",
"connected": "Connected", "connected": "متصل",
"offline": "Offline", "offline": "غير متصل",
"profilePicture": "Profile picture" "profilePicture": "صورة الملف الشخصي"
}, },
"board": { "board": {
"installManually": "Install Manually", "installManually": "ثبّت يدويا",
"installNow": "The \"{0} {1}\" core has to be installed for the currently selected \"{2}\" board. Do you want to install it now?", "installNow": "نواة \"{0} {1}\" يجب تثبيتها للوحة \"{2}\" التي تم اختيارها . هل تريد تثبيتها الان ؟",
"configDialogTitle": "Select Other Board & Port", "configDialogTitle": "اختر لوحات اخرى و المنفذ",
"configDialog1": "Select both a Board and a Port if you want to upload a sketch.", "configDialog1": "اختر لوحة و منفذ معا اذا اردت ان ترفع السكتش",
"configDialog2": "If you only select a Board you will be able to compile, but not to upload your sketch.", "configDialog2": "اذا قمت باختيار لوحة فقط ستسطيع ان تترجم لكن بدون ان ترفع المشروع",
"pleasePickBoard": "Please pick a board connected to the port you have selected.", "pleasePickBoard": "من فضلك اختر لوحة متصلة على المنفذ الذي اخترته",
"showAllAvailablePorts": "Shows all available ports when enabled", "showAllAvailablePorts": "يظهر كل المنافذ المتاحة عند تفعيله",
"programmer": "Programmer", "programmer": "المبرمجة",
"succesfullyInstalledPlatform": "Successfully installed platform {0}:{1}", "succesfullyInstalledPlatform": "تم تثبيت المنصة {0}:{1} بنجاح",
"succesfullyUninstalledPlatform": "Successfully uninstalled platform {0}:{1}", "succesfullyUninstalledPlatform": "تم الغاء تثبيت المنصة {0}:{1} بنجاح",
"couldNotFindPreviouslySelected": "Could not find previously selected board '{0}' in installed platform '{1}'. Please manually reselect the board you want to use. Do you want to reselect it now?", "couldNotFindPreviouslySelected": "تعذر ايجاد اللوحة '{0}' المختارة مسبقا في المنصة المثبتة '{1}' . الرجاء اعادة اختيار اللوحة التي تريد استعمالها يدويا . هل تريد باعادة الاختيار الان؟",
"reselectLater": "Reselect later", "reselectLater": "اعد الاختيار لاحقا",
"noneSelected": "No boards selected.", "noneSelected": "لم يتم اختيار اي لوحة",
"noPortsSelected": "No ports selected for board: '{0}'.", "noPortsSelected": "لا يوجد اية منافذ متاحة للوحة '{0}'",
"noFQBN": "The FQBN is not available for the selected board \"{0}\". Do you have the corresponding core installed?", "noFQBN": "FQBN غير متاح للوحة المختارة \"{0}\" . هل قمت بتثبيت النواة المعنية ؟",
"openBoardsConfig": "Select other board and port…", "openBoardsConfig": "قم باختيار لوحة و منفذ مختلفين",
"boardListItem": "{0} at {1}", "boardListItem": "{0} في {1}",
"selectBoardForInfo": "Please select a board to obtain board info.", "selectBoardForInfo": "الرجاء اختيار لوحة من احل الحصول على معلومات اللوحة",
"platformMissing": "The platform for the selected '{0}' board is not installed.", "platformMissing": "المنصة للّوحة المختارة '{0}' غير مثبتة",
"selectPortForInfo": "Please select a port to obtain board info.", "selectPortForInfo": "الرجاء اختيار منفذ من اجل الحصول على معلومات اللوحة",
"boardInfo": "معلومات اللوحة", "boardInfo": "معلومات اللوحة",
"board": "Board{0}", "board": "اللوحة {0}",
"port": "Port{0}", "port": "المنفذ {0}",
"getBoardInfo": "Get Board Info", "getBoardInfo": "الحصول على معلومات اللوحة",
"inSketchbook": " (in Sketchbook)" "inSketchbook": "(داخل ملف المشاريع)"
}, },
"boardsManager": "مدير اللوحة", "boardsManager": "مدير اللوحة",
"about": { "about": {
"label": "About {0}", "label": "حول {0}",
"detail": "Version: {0}\nDate: {1}{2}\nCLI Version: {3}{4} [{5}]\n\n{6}" "detail": "النسخة : {0}\nالتاريخ : {1} {2} \nنسخة موجه سطر الاوامر CLI {3}{4} [{5}] \n{6}"
}, },
"contributions": { "contributions": {
"addFile": "اضف ملف...", "addFile": "اضف ملف...",
"replaceTitle": "Replace", "replaceTitle": "استبدال",
"fileAdded": "One file added to the sketch." "fileAdded": "تمت اضافة ملف واحد الى المشروع"
}, },
"replaceMsg": "Replace the existing version of {0}?", "replaceMsg": "هل تريد استبدال النسخة الحالية من {0} ؟",
"library": { "library": {
"addZip": "اضف مكتبة .ZIP ...", "addZip": "اضف مكتبة .ZIP ...",
"zipLibrary": "Library", "zipLibrary": "المكتبة",
"overwriteExistingLibrary": "Do you want to overwrite the existing library?", "overwriteExistingLibrary": "هل تريد الكتابة فوق المكتبة الحالية ؟",
"successfullyInstalledZipLibrary": "Successfully installed library from {0} archive", "successfullyInstalledZipLibrary": "تم تثبيت المكتبة من الارشيف {0} بنجاح",
"namedLibraryAlreadyExists": "A library folder named {0} already exists. Do you want to overwrite it?", "namedLibraryAlreadyExists": "يوجد ملف مكتبة باسم {0} مسبقا . هل تريد الكتابة فوقه ؟",
"libraryAlreadyExists": "A library already exists. Do you want to overwrite it?", "libraryAlreadyExists": "المكتبة موجودة مسبقا . هل تريد الكتابة فوقها ؟",
"include": "Include Library", "include": "ضمّن مكتبة",
"manageLibraries": "Manage Libraries...", "manageLibraries": "ادارة المكتبات",
"arduinoLibraries": "Arduino libraries", "arduinoLibraries": "مكتبات Arduino",
"contributedLibraries": "Contributed libraries", "contributedLibraries": "المكتبات التي سوهم بها",
"title": "Library Manager", "title": "مدير المكتبات",
"needsOneDependency": "The library <b>{0}:{1}</b> needs another dependency currently not installed:", "needsOneDependency": "المكتبة <b>{0}:{1}</b> تحتاج الى تبعات اخرى غير مثبتة حاليا",
"needsMultipleDependencies": "The library <b>{0}:{1}</b> needs some other dependencies currently not installed:", "needsMultipleDependencies": "المكتبة <b>{0}:{1}</b> تحتاج الى تبعات اخرى غير مثبتة حاليا",
"installOneMissingDependency": "Would you like to install the missing dependency?", "installOneMissingDependency": "هل تريد تثبيت التبعية المفقودة ؟",
"installMissingDependencies": "Would you like to install all the missing dependencies?", "installMissingDependencies": "هل تريد تثبيت التبعيات المفقودة؟",
"dependenciesForLibrary": "Dependencies for library {0}:{1}", "dependenciesForLibrary": "تبعيات المكتبة {0}:{1}",
"installAll": "Install all", "installAll": "تثبيت الكل",
"installOnly": "Install {0} only", "installOnly": "تثبيت {0} فقط",
"installedSuccessfully": "Successfully installed library {0}:{1}", "installedSuccessfully": "تم تثبيت المكتبة {0}:{1} بنجاح",
"uninstalledSuccessfully": "Successfully uninstalled library {0}:{1}" "uninstalledSuccessfully": "تم الغاء تثبيت المكتبة {0}:{1} بنجاح"
}, },
"selectZip": "Select a zip file containing the library you'd like to add", "selectZip": "اختر ملف .zip يحوي المكتبة التي تريد اضافتها",
"sketch": { "sketch": {
"archiveSketch": "ارشفة الشيفرة البرمجية", "archiveSketch": "ارشفة الشيفرة البرمجية",
"saveSketchAs": "Save sketch folder as...", "saveSketchAs": "حفظ ملف المشروع باسم ...",
"createdArchive": "Created archive '{0}'.", "createdArchive": "تم انشاء ارشيف '{0}'",
"new": "New", "new": "جديد",
"openRecent": "Open Recent", "openRecent": "فُتِحَ مؤخرا ",
"showFolder": "Show Sketch Folder", "showFolder": "اعرض ملف المشروع",
"sketch": "Sketch", "sketch": "مشروع",
"moving": "Moving", "moving": "يتم النقل",
"movingMsg": "The file \"{0}\" needs to be inside a sketch folder named \"{1}\".\nCreate this folder, move the file, and continue?", "movingMsg": "الملف \"{0}\" يجب ان يكون داخل مجلد مشروع مسمى \"{1}\"\nهل انشئ المجلد , ثم انقل الملف و اكمل ؟",
"cantOpen": "المجلد المسمى \"{0}\" موجود مسبقا. لا يمكن فتح الشيفرة البرمجية", "cantOpen": "المجلد المسمى \"{0}\" موجود مسبقا. لا يمكن فتح الشيفرة البرمجية",
"saveFolderAs": "Save sketch folder as...", "saveFolderAs": "احفظ مجلد المشروع باسم",
"sketchbook": "Sketchbook", "sketchbook": "مجلد المشاريع",
"upload": "رفع", "upload": "رفع",
"uploadUsingProgrammer": "Upload Using Programmer", "uploadUsingProgrammer": "الرفع باستخدام مبرمجة",
"userFieldsNotFoundError": "Can't find user fields for connected board", "userFieldsNotFoundError": "تعذر ايجاد حقول المستخدم للوحة المتصلة",
"doneUploading": "Done uploading.", "doneUploading": "تم الرفع بنجاح.",
"configureAndUpload": "Configure And Upload", "configureAndUpload": "تهيئة و رفع",
"verifyOrCompile": "Verify/Compile", "verifyOrCompile": "تحقق/ترجم",
"exportBinary": "Export Compiled Binary", "exportBinary": "تصدير الملف الثنائي المترجم",
"verify": "Verify", "verify": "تحقق",
"doneCompiling": "Done compiling.", "doneCompiling": "تمت الترجمة بنجاح.",
"couldNotConnectToSerial": "Could not reconnect to serial port. {0}", "couldNotConnectToSerial": "لا يمكن الاتصال بالمنفذ التسلسلي {0}",
"openSketchInNewWindow": "Open Sketch in New Window", "openSketchInNewWindow": "فتح المشروع في نافذة جديدة",
"openFolder": "Open Folder", "openFolder": "فتح المجلد",
"titleLocalSketchbook": "Local Sketchbook", "titleLocalSketchbook": "مجلد المشاريع المحلي",
"titleSketchbook": "Sketchbook", "titleSketchbook": "مجلد المشاريع",
"close": "Are you sure you want to close the sketch?" "close": "هل انت متاكد بانك تريد اغلاق المشروع ؟"
}, },
"bootloader": { "bootloader": {
"burnBootloader": "ثبت محمل برنامج الإقلاع", "burnBootloader": "ثبت محمل برنامج الإقلاع",
"doneBurningBootloader": "Done burning bootloader." "doneBurningBootloader": "تم حرق محمل الاقلاع"
}, },
"editor": { "editor": {
"copyForForum": "Copy for Forum (Markdown)", "copyForForum": "النسخ من اجل المنتدى ",
"commentUncomment": "ملاحظة/ الغاء الملاحظة", "commentUncomment": "ملاحظة/ الغاء الملاحظة",
"increaseIndent": "Increase Indent", "increaseIndent": "زيادة مسافة البادئة",
"decreaseIndent": "Decrease Indent", "decreaseIndent": "تقليل مسافة البادئة",
"increaseFontSize": "Increase Font Size", "increaseFontSize": "تكبير حجم الخط",
"decreaseFontSize": "تصغير حجم الخط", "decreaseFontSize": "تصغير حجم الخط",
"autoFormat": "تنسيق تلقائي" "autoFormat": "تنسيق تلقائي"
}, },
"examples": { "examples": {
"menu": "Examples", "menu": "أمثلة",
"couldNotInitializeExamples": "Could not initialize built-in examples.", "couldNotInitializeExamples": "تعذرت تهيئة الامثلة المدمجة",
"builtInExamples": "الأمثلة المدمجة", "builtInExamples": "الأمثلة المدمجة",
"customLibrary": "Examples from Custom Libraries", "customLibrary": "امثلة من مكتبات مخصصة",
"for": "Examples for {0}", "for": "امثلة ل {0}",
"forAny": "Examples for any board" "forAny": "أمثلة لأي لوحة"
}, },
"help": { "help": {
"search": "Search on Arduino.cc", "search": "البحث على Arduino.cc",
"keyword": "Type a keyword", "keyword": "ادخل كلمة مفتاحية",
"gettingStarted": "Getting Started", "gettingStarted": "البدء",
"environment": "Environment", "environment": "البيئة",
"troubleshooting": "Troubleshooting", "troubleshooting": "استكشاف الاخطاء و اصلاحها",
"reference": "Reference", "reference": "مراجع",
"findInReference": "Find in Reference", "findInReference": "ايجاد في مرجع",
"faq": "Frequently Asked Questions", "faq": "اسئلة متكررة",
"visit": "Visit Arduino.cc", "visit": "زيارة Arduino.cc",
"privacyPolicy": "Privacy Policy" "privacyPolicy": "سياسة الخصوصية"
}, },
"certificate": { "certificate": {
"uploadRootCertificates": "Upload SSL Root Certificates", "uploadRootCertificates": "رفع شهادات SSL Root",
"openContext": "Open context", "openContext": "افتح المحتوى",
"remove": "حذف", "remove": "حذف",
"upload": "رفع", "upload": "رفع",
"addURL": "Add URL to fetch SSL certificate", "addURL": "اضف URL لجلب شهادات SSL",
"enterURL": "Enter URL", "enterURL": "ادخل URL",
"selectCertificateToUpload": "1. Select certificate to upload", "selectCertificateToUpload": "1. اختر شهادة لرفعها",
"addNew": "Add New", "addNew": "اضافة جديد",
"selectDestinationBoardToUpload": "2. Select destination board and upload certificate", "selectDestinationBoardToUpload": "2. اختر وجهة اللوحة و ارفع الشهادة",
"uploadingCertificates": "Uploading certificates.", "uploadingCertificates": "جار رفع الشهادة",
"certificatesUploaded": "Certificates uploaded.", "certificatesUploaded": "تم رفع الشهادات",
"uploadFailed": "Upload failed. Please try again.", "uploadFailed": "فشل الرفع . الرجاء اعادة المحاولة لاحقا",
"selectBoard": "Select a board...", "selectBoard": "اختر لوحة ...",
"boardAtPort": "{0} at {1}", "boardAtPort": "{0} في {1}",
"noSupportedBoardConnected": "No supported board connected" "noSupportedBoardConnected": "لا يوجد اية لوحة مدعومة متصلة "
}, },
"firmware": { "firmware": {
"updater": "WiFi101 / WiFiNINA Firmware Updater", "updater": "محدث البرامج الثابتة ل WiFi101 / WiFiNINA ",
"selectBoard": "Select Board", "selectBoard": "اختر لوحة",
"checkUpdates": "Check Updates", "checkUpdates": "التحقق من التحديثات",
"selectVersion": "Select firmware version", "selectVersion": "اختر نسخة البرامج الثابتة",
"install": "تنصيب", "install": "تنصيب",
"overwriteSketch": "Installation will overwrite the Sketch on the board.", "overwriteSketch": "التثبيت سيكتب فوق المشروع على اللوحة",
"installingFirmware": "Installing firmware.", "installingFirmware": "جار تثبيت البرامج الثابتة",
"successfullyInstalled": "Firmware successfully installed.", "successfullyInstalled": "تم تثبيت البرامج الثابتة بنجاح",
"failedInstall": "Installation failed. Please try again." "failedInstall": "فشل التثبيت. الرجاء اعادة المحاولة لاحقا"
}, },
"dialog": { "dialog": {
"dontAskAgain": "Don't ask again" "dontAskAgain": "لا تسأل مرة اخرى"
}, },
"userFields": { "userFields": {
"cancel": "Cancel", "cancel": "الغاء",
"upload": "رفع" "upload": "رفع"
}, },
"serial": { "serial": {
"toggleTimestamp": "Toggle Timestamp", "toggleTimestamp": "تبديل الطابع الزمني",
"autoscroll": "Autoscroll", "autoscroll": "تمرير تلقائي",
"timestamp": "Timestamp", "timestamp": "الطابع الزمني",
"noLineEndings": "نهاية السطر غير موجودة", "noLineEndings": "نهاية السطر غير موجودة",
"newLine": "سطر جديد", "newLine": "سطر جديد",
"carriageReturn": "اعادة الحمل", "carriageReturn": "اعادة الحمل",
"newLineCarriageReturn": "كلاهما NL & CR", "newLineCarriageReturn": " NL & CR معاً",
"notConnected": "Not connected. Select a board and a port to connect automatically.", "notConnected": "غير متصل . اختر لوحة و منفذ للاتصال تلقائيا",
"message": "Message ({0} + Enter to send message to '{1}' on '{2}')", "message": "الرسالة ({0} + ادخل لارسال رسالة الى '{1}' على '{2}')",
"connectionBusy": "Connection failed. Serial port is busy: {0}", "connectionBusy": "تعذر الاتصال . المنفذ التسلسلي مشغول : {0}",
"disconnected": "Disconnected {0} from {1}.", "disconnected": "انقطع اتصال {0} من {1}",
"unexpectedError": "Unexpected error. Reconnecting {0} on port {1}.", "unexpectedError": "خطأ غير متوقع . جار اعادة اتصال {0} على المنفذ {1}",
"failedReconnect": "Failed to reconnect {0} to serial port after 10 consecutive attempts. The {1} serial port is busy.", "failedReconnect": "فشل اعادة الاتصال بالمنفذ التسلسلي {0}بعد 10 محاولات متتالية . المنفذ التسلسلي{1} مشغول",
"reconnect": "Reconnecting {0} to {1} in {2} seconds..." "reconnect": "جار اعادة اتصال {0} الى {1} خلال {2} ثانية"
}, },
"component": { "component": {
"uninstall": "Uninstall", "uninstall": "الغاء التثبيت",
"uninstallMsg": "Do you want to uninstall {0}?", "uninstallMsg": "هل تريد الغاء تثبيت {0}؟",
"by": "by", "by": "بواسطة",
"version": "النسخة {0}", "version": "النسخة {0}",
"moreInfo": "More info", "moreInfo": "عرض المزيد",
"install": "تنصيب", "install": "تنصيب",
"filterSearch": "ترشيح بحثك..." "filterSearch": "ترشيح بحثك..."
}, },
"electron": { "electron": {
"couldNotSave": "Could not save the sketch. Please copy your unsaved work into your favorite text editor, and restart the IDE.", "couldNotSave": "تعذر حفظ المشروع . الرجاء نسخ عملك الغير محفوظ الى محرر النصوص المفضل لديك و اعادة تشغيل Arduino IDE",
"unsavedChanges": "Any unsaved changes will not be saved." "unsavedChanges": "اي تغييرات لم تحفظ لن يتم حفظها"
}, },
"compile": { "compile": {
"error": "Compilation error: {0}" "error": "خطا في الترجمة : {0}"
}, },
"upload": { "upload": {
"error": "{0} error: {1}" "error": "خطا {0} : {1}"
}, },
"burnBootloader": { "burnBootloader": {
"error": "Error while burning the bootloader: {0}" "error": "خطا اثناء حرق محمل الاقلاع : {0}"
} }
}, },
"theia": { "theia": {
"core": { "core": {
"couldNotSave": "Could not save the sketch. Please copy your unsaved work into your favorite text editor, and restart the IDE.", "couldNotSave": "تعذر حفظ المشروع . الرجاء نسخ عملك الغير محفوظ الى محرر النصوص المفضل لديك و اعادة تشغيل Arduino IDE",
"offline": "Offline", "offline": "غير متصل",
"daemonOffline": "CLI Daemon Offline", "daemonOffline": "CLI Daemon غير متصل",
"cannotConnectBackend": "Cannot connect to the backend.", "cannotConnectBackend": "تعذر الاتصال بالخلفية",
"cannotConnectDaemon": "Cannot connect to the CLI daemon." "cannotConnectDaemon": "تعذر الاتصال ب CLI daemon"
}, },
"debug": { "debug": {
"start": "Start...", "start": "البدء...",
"typeNotSupported": "The debug session type \"{0}\" is not supported.", "typeNotSupported": "The debug session type \"{0}\" is not supported.",
"startError": "There was an error starting the debug session, check the logs for more details." "startError": "There was an error starting the debug session, check the logs for more details."
}, },
@@ -332,19 +332,19 @@
"unsavedTitle": "Unsaved {0}" "unsavedTitle": "Unsaved {0}"
}, },
"messages": { "messages": {
"expand": "Expand", "expand": "توسيع",
"collapse": "Collapse" "collapse": "تقليص"
}, },
"workspace": { "workspace": {
"fileNewName": "Name for new file", "fileNewName": "Name for new file",
"invalidFilename": "Invalid filename.", "invalidFilename": "Invalid filename.",
"invalidExtension": "\".{0}\" امتداد غير صالح", "invalidExtension": "\".{0}\" امتداد غير صالح",
"newFileName": "New name for file", "newFileName": "الاسم الجديد لملف",
"deleteCurrentSketch": "Do you want to delete the current sketch?", "deleteCurrentSketch": "هل تريد حذف المشروع الحالي؟",
"sketchDirectoryError": "There was an error creating the sketch directory. See the log for more details. The application will probably not work as expected." "sketchDirectoryError": "There was an error creating the sketch directory. See the log for more details. The application will probably not work as expected."
} }
}, },
"cloud": { "cloud": {
"GoToCloud": "GO TO CLOUD" "GoToCloud": "الانتقال الى السحابة"
} }
} }

350
i18n/ca.json Normal file
View File

@@ -0,0 +1,350 @@
{
"arduino": {
"common": {
"offlineIndicator": "You appear to be offline. Without an Internet connection, the Arduino CLI might not be able to download the required resources and could cause malfunction. Please connect to the Internet and restart the application.",
"noBoardSelected": "No board selected",
"selectedOn": "on {0}",
"notConnected": "[not connected]",
"serialMonitor": "Serial Monitor",
"oldFormat": "The '{0}' still uses the old `.pde` format. Do you want to switch to the new `.ino` extension?",
"later": "Later",
"selectBoard": "Select Board",
"unknown": "Unknown",
"processing": "Processing",
"saveChangesToSketch": "Do you want to save changes to this sketch before closing?",
"loseChanges": "If you don't save, your changes will be lost."
},
"ide-updater": {
"errorCheckingForUpdates": "Error while checking for Arduino IDE updates.\n{0}",
"notNowButton": "Not now",
"versionDownloaded": "Arduino IDE {0} has been downloaded.",
"closeToInstallNotice": "Close the software and install the update on your machine.",
"closeAndInstallButton": "Close and Install",
"downloadingNotice": "Downloading the latest version of the Arduino IDE.",
"updateAvailable": "Update Available",
"newVersionAvailable": "A new version of Arduino IDE ({0}) is available for download.",
"skipVersionButton": "Skip Version",
"downloadButton": "Download",
"goToDownloadPage": "An update for the Arduino IDE is available, but we're not able to download and install it automatically. Please go to the download page and download the latest version from there.",
"goToDownloadButton": "Go To Download",
"ideUpdaterDialog": "Software Update",
"noUpdatesAvailable": "There are no recent updates available for the Arduino IDE"
},
"menu": {
"sketch": "Sketch",
"tools": "Tools"
},
"debug": {
"optimizeForDebugging": "Optimize for Debugging",
"debugWithMessage": "Debug - {0}",
"noPlatformInstalledFor": "Platform is not installed for '{0}'",
"debuggingNotSupported": "Debugging is not supported by '{0}'"
},
"preferences": {
"language.log": "True if the Arduino Language Server should generate log files into the sketch folder. Otherwise, false. It's false by default.",
"compile.verbose": "True for verbose compile output. False by default",
"compile.warnings": "Tells gcc which warning level to use. It's 'None' by default",
"upload.verbose": "True for verbose upload output. False by default.",
"window.autoScale": "True if the user interface automatically scales with the font size.",
"window.zoomLevel": "Adjust the zoom level of the window. The original size is 0 and each increment above (e.g. 1) or below (e.g. -1) represents zooming 20% larger or smaller. You can also enter decimals to adjust the zoom level with a finer granularity.",
"ide.updateChannel": "Release channel to get updated from. 'stable' is the stable release, 'nightly' is the latest development build.",
"board.certificates": "List of certificates that can be uploaded to boards",
"sketchbook.showAllFiles": "True to show all sketch files inside the sketch. It is false by default.",
"cloud.enabled": "True if the sketch sync functions are enabled. Defaults to true.",
"cloud.pull.warn": "True if users should be warned before pulling a cloud sketch. Defaults to true.",
"cloud.push.warn": "True if users should be warned before pushing a cloud sketch. Defaults to true.",
"cloud.pushpublic.warn": "True if users should be warned before pushing a public sketch to the cloud. Defaults to true.",
"cloud.sketchSyncEnpoint": "The endpoint used to push and pull sketches from a backend. By default it points to Arduino Cloud API.",
"auth.clientID": "The OAuth2 client ID.",
"auth.domain": "The OAuth2 domain.",
"auth.audience": "The OAuth2 audience.",
"auth.registerUri": "The URI used to register a new user.",
"network": "Network",
"sketchbook.location": "Sketchbook location",
"browse": "Browse",
"files.inside.sketches": "Show files inside Sketches",
"editorFontSize": "Editor font size",
"interfaceScale": "Interface scale",
"showVerbose": "Show verbose output during",
"compilerWarnings": "Compiler warnings",
"automatic": "Automatic",
"compile": "compile",
"upload": "upload",
"verifyAfterUpload": "Verify code after upload",
"editorQuickSuggestions": "Editor Quick Suggestions",
"additionalManagerURLs": "Additional Boards Manager URLs",
"noProxy": "No proxy",
"manualProxy": "Manual proxy configuration",
"newSketchbookLocation": "Select new sketchbook location",
"choose": "Choose",
"enterAdditionalURLs": "Enter additional URLs, one for each row",
"unofficialBoardSupport": "Click for a list of unofficial board support URLs",
"invalid.sketchbook.location": "Invalid sketchbook location: {0}",
"invalid.editorFontSize": "Invalid editor font size. It must be a positive integer.",
"invalid.theme": "Invalid theme."
},
"cloud": {
"signIn": "SIGN IN",
"signOut": "Sign Out",
"chooseSketchVisibility": "Choose visibility of your Sketch:",
"privateVisibility": "Private. Only you can view the Sketch.",
"publicVisibility": "Public. Anyone with the link can view the Sketch.",
"link": "Link:",
"embed": "Embed:",
"cloudSketchbook": "Cloud Sketchbook",
"shareSketch": "Share Sketch",
"showHideRemoveSketchbook": "Show/Hide Remote Sketchbook",
"pullSketch": "Pull Sketch",
"openInCloudEditor": "Open in Cloud Editor",
"options": "Options...",
"share": "Share...",
"remote": "Remote",
"emptySketchbook": "Your Sketchbook is empty",
"visitArduinoCloud": "Visit Arduino Cloud to create Cloud Sketches.",
"signInToCloud": "Sign in to Arduino Cloud",
"syncEditSketches": "Sync and edit your Arduino Cloud Sketches",
"learnMore": "Learn more",
"continue": "Continue",
"pushSketch": "Push Sketch",
"pushSketchMsg": "This is a Public Sketch. Before pushing, make sure any sensitive information is defined in arduino_secrets.h files. You can make a Sketch private from the Share panel.",
"pull": "Pull",
"pullSketchMsg": "Pulling this Sketch from the Cloud will overwrite its local version. Are you sure you want to continue?",
"donePulling": "Done pulling {0}.",
"notYetPulled": "Cannot push to Cloud. It is not yet pulled.",
"push": "Push",
"pullFirst": "You have to pull first to be able to push to the Cloud.",
"donePushing": "Done pushing {0}.",
"connected": "Connected",
"offline": "Offline",
"profilePicture": "Profile picture"
},
"board": {
"installManually": "Install Manually",
"installNow": "The \"{0} {1}\" core has to be installed for the currently selected \"{2}\" board. Do you want to install it now?",
"configDialogTitle": "Select Other Board & Port",
"configDialog1": "Select both a Board and a Port if you want to upload a sketch.",
"configDialog2": "If you only select a Board you will be able to compile, but not to upload your sketch.",
"pleasePickBoard": "Please pick a board connected to the port you have selected.",
"showAllAvailablePorts": "Shows all available ports when enabled",
"programmer": "Programmer",
"succesfullyInstalledPlatform": "Successfully installed platform {0}:{1}",
"succesfullyUninstalledPlatform": "Successfully uninstalled platform {0}:{1}",
"couldNotFindPreviouslySelected": "Could not find previously selected board '{0}' in installed platform '{1}'. Please manually reselect the board you want to use. Do you want to reselect it now?",
"reselectLater": "Reselect later",
"noneSelected": "No boards selected.",
"noPortsSelected": "No ports selected for board: '{0}'.",
"noFQBN": "The FQBN is not available for the selected board \"{0}\". Do you have the corresponding core installed?",
"openBoardsConfig": "Select other board and port…",
"boardListItem": "{0} at {1}",
"selectBoardForInfo": "Please select a board to obtain board info.",
"platformMissing": "The platform for the selected '{0}' board is not installed.",
"selectPortForInfo": "Please select a port to obtain board info.",
"boardInfo": "Board Info",
"board": "Board{0}",
"port": "Port{0}",
"getBoardInfo": "Get Board Info",
"inSketchbook": " (in Sketchbook)"
},
"boardsManager": "Boards Manager",
"about": {
"label": "About {0}",
"detail": "Version: {0}\nDate: {1}{2}\nCLI Version: {3}{4} [{5}]\n\n{6}"
},
"contributions": {
"addFile": "Add File",
"replaceTitle": "Replace",
"fileAdded": "One file added to the sketch."
},
"replaceMsg": "Replace the existing version of {0}?",
"library": {
"addZip": "Add .ZIP Library...",
"zipLibrary": "Library",
"overwriteExistingLibrary": "Do you want to overwrite the existing library?",
"successfullyInstalledZipLibrary": "Successfully installed library from {0} archive",
"namedLibraryAlreadyExists": "A library folder named {0} already exists. Do you want to overwrite it?",
"libraryAlreadyExists": "A library already exists. Do you want to overwrite it?",
"include": "Include Library",
"manageLibraries": "Manage Libraries...",
"arduinoLibraries": "Arduino libraries",
"contributedLibraries": "Contributed libraries",
"title": "Library Manager",
"needsOneDependency": "The library <b>{0}:{1}</b> needs another dependency currently not installed:",
"needsMultipleDependencies": "The library <b>{0}:{1}</b> needs some other dependencies currently not installed:",
"installOneMissingDependency": "Would you like to install the missing dependency?",
"installMissingDependencies": "Would you like to install all the missing dependencies?",
"dependenciesForLibrary": "Dependencies for library {0}:{1}",
"installAll": "Install all",
"installOnly": "Install {0} only",
"installedSuccessfully": "Successfully installed library {0}:{1}",
"uninstalledSuccessfully": "Successfully uninstalled library {0}:{1}"
},
"selectZip": "Select a zip file containing the library you'd like to add",
"sketch": {
"archiveSketch": "Archive Sketch",
"saveSketchAs": "Save sketch folder as...",
"createdArchive": "Created archive '{0}'.",
"new": "New",
"openRecent": "Open Recent",
"showFolder": "Show Sketch Folder",
"sketch": "Sketch",
"moving": "Moving",
"movingMsg": "The file \"{0}\" needs to be inside a sketch folder named \"{1}\".\nCreate this folder, move the file, and continue?",
"cantOpen": "A folder named \"{0}\" already exists. Can't open sketch.",
"saveFolderAs": "Save sketch folder as...",
"sketchbook": "Sketchbook",
"upload": "Upload",
"uploadUsingProgrammer": "Upload Using Programmer",
"userFieldsNotFoundError": "Can't find user fields for connected board",
"doneUploading": "Done uploading.",
"configureAndUpload": "Configure And Upload",
"verifyOrCompile": "Verify/Compile",
"exportBinary": "Export Compiled Binary",
"verify": "Verify",
"doneCompiling": "Done compiling.",
"couldNotConnectToSerial": "Could not reconnect to serial port. {0}",
"openSketchInNewWindow": "Open Sketch in New Window",
"openFolder": "Open Folder",
"titleLocalSketchbook": "Local Sketchbook",
"titleSketchbook": "Sketchbook",
"close": "Are you sure you want to close the sketch?"
},
"bootloader": {
"burnBootloader": "Burn Bootloader",
"doneBurningBootloader": "Done burning bootloader."
},
"editor": {
"copyForForum": "Copy for Forum (Markdown)",
"commentUncomment": "Comment/Uncomment",
"increaseIndent": "Increase Indent",
"decreaseIndent": "Decrease Indent",
"increaseFontSize": "Increase Font Size",
"decreaseFontSize": "Decrease Font Size",
"autoFormat": "Auto Format"
},
"examples": {
"menu": "Examples",
"couldNotInitializeExamples": "Could not initialize built-in examples.",
"builtInExamples": "Built-in examples",
"customLibrary": "Examples from Custom Libraries",
"for": "Examples for {0}",
"forAny": "Examples for any board"
},
"help": {
"search": "Search on Arduino.cc",
"keyword": "Type a keyword",
"gettingStarted": "Getting Started",
"environment": "Environment",
"troubleshooting": "Troubleshooting",
"reference": "Reference",
"findInReference": "Find in Reference",
"faq": "Frequently Asked Questions",
"visit": "Visit Arduino.cc",
"privacyPolicy": "Privacy Policy"
},
"certificate": {
"uploadRootCertificates": "Upload SSL Root Certificates",
"openContext": "Open context",
"remove": "Remove",
"upload": "Upload",
"addURL": "Add URL to fetch SSL certificate",
"enterURL": "Enter URL",
"selectCertificateToUpload": "1. Select certificate to upload",
"addNew": "Add New",
"selectDestinationBoardToUpload": "2. Select destination board and upload certificate",
"uploadingCertificates": "Uploading certificates.",
"certificatesUploaded": "Certificates uploaded.",
"uploadFailed": "Upload failed. Please try again.",
"selectBoard": "Select a board...",
"boardAtPort": "{0} at {1}",
"noSupportedBoardConnected": "No supported board connected"
},
"firmware": {
"updater": "WiFi101 / WiFiNINA Firmware Updater",
"selectBoard": "Select Board",
"checkUpdates": "Check Updates",
"selectVersion": "Select firmware version",
"install": "Install",
"overwriteSketch": "Installation will overwrite the Sketch on the board.",
"installingFirmware": "Installing firmware.",
"successfullyInstalled": "Firmware successfully installed.",
"failedInstall": "Installation failed. Please try again."
},
"dialog": {
"dontAskAgain": "Don't ask again"
},
"userFields": {
"cancel": "Cancel",
"upload": "Upload"
},
"serial": {
"toggleTimestamp": "Toggle Timestamp",
"autoscroll": "Autoscroll",
"timestamp": "Timestamp",
"noLineEndings": "No Line Ending",
"newLine": "New Line",
"carriageReturn": "Carriage Return",
"newLineCarriageReturn": "Both NL & CR",
"notConnected": "Not connected. Select a board and a port to connect automatically.",
"message": "Message ({0} + Enter to send message to '{1}' on '{2}')",
"connectionBusy": "Connection failed. Serial port is busy: {0}",
"disconnected": "Disconnected {0} from {1}.",
"unexpectedError": "Unexpected error. Reconnecting {0} on port {1}.",
"failedReconnect": "Failed to reconnect {0} to serial port after 10 consecutive attempts. The {1} serial port is busy.",
"reconnect": "Reconnecting {0} to {1} in {2} seconds..."
},
"component": {
"uninstall": "Uninstall",
"uninstallMsg": "Do you want to uninstall {0}?",
"by": "by",
"version": "Version {0}",
"moreInfo": "More info",
"install": "INSTALL",
"filterSearch": "Filter your search..."
},
"electron": {
"couldNotSave": "Could not save the sketch. Please copy your unsaved work into your favorite text editor, and restart the IDE.",
"unsavedChanges": "Any unsaved changes will not be saved."
},
"compile": {
"error": "Compilation error: {0}"
},
"upload": {
"error": "{0} error: {1}"
},
"burnBootloader": {
"error": "Error while burning the bootloader: {0}"
}
},
"theia": {
"core": {
"couldNotSave": "Could not save the sketch. Please copy your unsaved work into your favorite text editor, and restart the IDE.",
"offline": "Offline",
"daemonOffline": "CLI Daemon Offline",
"cannotConnectBackend": "Cannot connect to the backend.",
"cannotConnectDaemon": "Cannot connect to the CLI daemon."
},
"debug": {
"start": "Start...",
"typeNotSupported": "The debug session type \"{0}\" is not supported.",
"startError": "There was an error starting the debug session, check the logs for more details."
},
"editor": {
"unsavedTitle": "Unsaved {0}"
},
"messages": {
"expand": "Expand",
"collapse": "Collapse"
},
"workspace": {
"fileNewName": "Name for new file",
"invalidFilename": "Invalid filename.",
"invalidExtension": ".{0} is not a valid extension",
"newFileName": "New name for file",
"deleteCurrentSketch": "Do you want to delete the current sketch?",
"sketchDirectoryError": "There was an error creating the sketch directory. See the log for more details. The application will probably not work as expected."
}
},
"cloud": {
"GoToCloud": "GO TO CLOUD"
}
}

View File

@@ -41,19 +41,19 @@
"debuggingNotSupported": "Debugging není podporován s '{0}'" "debuggingNotSupported": "Debugging není podporován s '{0}'"
}, },
"preferences": { "preferences": {
"language.log": "True if the Arduino Language Server should generate log files into the sketch folder. Otherwise, false. It's false by default.", "language.log": "Ano pokud by jazykový server pro Arduino měl generovat logovací soubory do složky se sketchi, jinak ne. Ne je výchozí hodnota.",
"compile.verbose": "True for verbose compile output. False by default", "compile.verbose": "Ano pro podrobný výstup při kompilaci. Ne je výchozí hodnota. ",
"compile.warnings": "Tells gcc which warning level to use. It's 'None' by default", "compile.warnings": "Řekne gcc který stupeň varování se má použít. \"Žádný\" je výchozí hodnota. ",
"upload.verbose": "True for verbose upload output. False by default.", "upload.verbose": "Ano pro podrobný výstup při nahrávání. Ne je výchozí hodnota. ",
"window.autoScale": "True if the user interface automatically scales with the font size.", "window.autoScale": "Ano pokud se měřítko uživatelského prostředí automaticky mění s velikostí písma. ",
"window.zoomLevel": "Adjust the zoom level of the window. The original size is 0 and each increment above (e.g. 1) or below (e.g. -1) represents zooming 20% larger or smaller. You can also enter decimals to adjust the zoom level with a finer granularity.", "window.zoomLevel": "Přizpůsobení přiblížení okna. Originální velikost je 0, zvýšení (např. o 1) nebo snížení (např. o -1) znamená 20% přiblížení nebo oddálení. Můžete použít desetinná čísla pro jemnější přizpůsobení.",
"ide.updateChannel": "Release channel to get updated from. 'stable' is the stable release, 'nightly' is the latest development build.", "ide.updateChannel": "Výběr kanálu pro aktualizace. 'stable' pro stabilní vydání, 'nightly' pro nejnovější vývojové verze.",
"board.certificates": "Seznam certifikátů, které mohou být nahrány na desky", "board.certificates": "Seznam certifikátů, které mohou být nahrány na desky",
"sketchbook.showAllFiles": "True to show all sketch files inside the sketch. It is false by default.", "sketchbook.showAllFiles": "Ano pro zobrazení všech souborů sketche. Ne je výchozí hodnota. ",
"cloud.enabled": "True if the sketch sync functions are enabled. Defaults to true.", "cloud.enabled": "Ano pokud je povolená automatická synchronizace sketche. Ano je výchozí hodnota. ",
"cloud.pull.warn": "True if users should be warned before pulling a cloud sketch. Defaults to true.", "cloud.pull.warn": "Ano pokud by měl být uživatel varován před stahováním cloud sketche. Ano je výchozí hodnota. ",
"cloud.push.warn": "True if users should be warned before pushing a cloud sketch. Defaults to true.", "cloud.push.warn": "Ano pokud by měl být uživatel varován před odesláním cloud sketche. Ano je výchozí hodnota. ",
"cloud.pushpublic.warn": "True if users should be warned before pushing a public sketch to the cloud. Defaults to true.", "cloud.pushpublic.warn": "Ano pokud by měl být uživatel varován před odesláním veřejné sketche do cloudu. Ano je výchozí hodnota. ",
"cloud.sketchSyncEnpoint": "Endpoint použitý pro stahování a odesílání sketchí z backendu. Ve výchozím stavu je toto směrováno na Arduino Cloud API.", "cloud.sketchSyncEnpoint": "Endpoint použitý pro stahování a odesílání sketchí z backendu. Ve výchozím stavu je toto směrováno na Arduino Cloud API.",
"auth.clientID": "OAuth2 klient ID", "auth.clientID": "OAuth2 klient ID",
"auth.domain": "Doména OAuth2 ", "auth.domain": "Doména OAuth2 ",

View File

@@ -3,348 +3,348 @@
"common": { "common": {
"offlineIndicator": "Al parecer no estás en línea. Sin una conexión a internet, el CLI de Arduino no podrá descargar los recursos necesarios, lo cual puede ocasionar fallos. Por favor, conecte a internet y reinicie la aplicación.", "offlineIndicator": "Al parecer no estás en línea. Sin una conexión a internet, el CLI de Arduino no podrá descargar los recursos necesarios, lo cual puede ocasionar fallos. Por favor, conecte a internet y reinicie la aplicación.",
"noBoardSelected": "Ninguna placa seleccionada.", "noBoardSelected": "Ninguna placa seleccionada.",
"selectedOn": "on {0}", "selectedOn": "on 1{0}\n ",
"notConnected": "[not connected]", "notConnected": "[no conectado]",
"serialMonitor": "Monitor Serie", "serialMonitor": "Monitor Serie",
"oldFormat": "El '{0}' aún usa el antiguo formato `.pde` . ¿Deseas cambiar a la nueva extensión `.ino`?.", "oldFormat": "La página '{0}' sigue utilizando el formato antiguo `.pde`. ¿Quieres cambiar a la nueva extensión `.ino`?",
"later": "Later", "later": "Más tarde",
"selectBoard": "Seleccionar Placa", "selectBoard": "Seleccionar Placa",
"unknown": "Unknown", "unknown": "Desconocido",
"processing": "Procesando", "processing": "Procesando",
"saveChangesToSketch": "¿Deseas guardar los cambios en este código antes de cerrar?", "saveChangesToSketch": "¿Quieres guardar los cambios en este sketch antes de cerrar?",
"loseChanges": "Si no guardas, perderás los cambios." "loseChanges": "Si no guardas, tus cambios se perderán."
}, },
"ide-updater": { "ide-updater": {
"errorCheckingForUpdates": "Error while checking for Arduino IDE updates.\n{0}", "errorCheckingForUpdates": "Error al comprobar las actualizaciones del IDE de Arduino.\n{0}",
"notNowButton": "Not now", "notNowButton": "Ahora no",
"versionDownloaded": "Arduino IDE {0} has been downloaded.", "versionDownloaded": "Arduino IDE 1{0} se ha descargado.",
"closeToInstallNotice": "Close the software and install the update on your machine.", "closeToInstallNotice": "Cierra el programa e instala la actualización en tu máquina.",
"closeAndInstallButton": "Close and Install", "closeAndInstallButton": "Cerrar e instalar",
"downloadingNotice": "Downloading the latest version of the Arduino IDE.", "downloadingNotice": "Descargando la última versión del Arduino IDE.",
"updateAvailable": "Update Available", "updateAvailable": "Actualización disponible",
"newVersionAvailable": "A new version of Arduino IDE ({0}) is available for download.", "newVersionAvailable": "Una nueva versión del Arduino IDE ({0}) está disponible para descargar.",
"skipVersionButton": "Skip Version", "skipVersionButton": "Omitir versión",
"downloadButton": "Download", "downloadButton": "Descargar",
"goToDownloadPage": "An update for the Arduino IDE is available, but we're not able to download and install it automatically. Please go to the download page and download the latest version from there.", "goToDownloadPage": "Una nueva versión del Arduino IDE está disponible, pero no es posible descargarla e instalarla automáticamente. Por favor, diríjase a la página de descarga y descargue la última versión desde allí.",
"goToDownloadButton": "Go To Download", "goToDownloadButton": "Actualización de Software",
"ideUpdaterDialog": "Software Update", "ideUpdaterDialog": "Actualización de Software",
"noUpdatesAvailable": "There are no recent updates available for the Arduino IDE" "noUpdatesAvailable": "No hay actualizaciones recientes disponibles para el Arduino IDE"
}, },
"menu": { "menu": {
"sketch": "Programa", "sketch": "Sketch",
"tools": "Herramientas" "tools": "Herramientas"
}, },
"debug": { "debug": {
"optimizeForDebugging": "Optimizar para depuración", "optimizeForDebugging": "Optimizar para depuración",
"debugWithMessage": "Debug - {0}", "debugWithMessage": "Debug - {0}",
"noPlatformInstalledFor": "La plataforma no está instalada para '{0}'", "noPlatformInstalledFor": "La plataforma no está instalada para '{0}'",
"debuggingNotSupported": "La depuracion no esta soportada por '{0}'" "debuggingNotSupported": "La depuración no está soportada por '{0}'"
}, },
"preferences": { "preferences": {
"language.log": "True if the Arduino Language Server should generate log files into the sketch folder. Otherwise, false. It's false by default.", "language.log": "Verdadero si el Servidor de Lenguaje Arduino debe generar archivos de registro en la carpeta del sketch. En caso contrario, falso. Por defecto es falso.",
"compile.verbose": "True for verbose compile output. False by default", "compile.verbose": "Verdadero para compilación detallada. Falso por defecto",
"compile.warnings": "Tells gcc which warning level to use. It's 'None' by default", "compile.warnings": "Indica a gcc qué nivel de advertencia usar. Por defecto es \"Ninguno\"",
"upload.verbose": "True for verbose upload output. False by default.", "upload.verbose": "Verdadero para una salida verbosa de la carga. Falso por defecto.",
"window.autoScale": "True if the user interface automatically scales with the font size.", "window.autoScale": "Verdadero si la interfaz de usuario se escala automáticamente con el tamaño de la fuente.",
"window.zoomLevel": "Adjust the zoom level of the window. The original size is 0 and each increment above (e.g. 1) or below (e.g. -1) represents zooming 20% larger or smaller. You can also enter decimals to adjust the zoom level with a finer granularity.", "window.zoomLevel": "Ajusta el nivel de zoom de la ventana. El tamaño original es 0 y cada incremento por encima (p. ej. 1) o por debajo (p. ej. -1) representa un zoom un 20 % más grande o más pequeño. También puedes introducir decimales para ajustar el nivel de zoom con una granularidad más fina.",
"ide.updateChannel": "Release channel to get updated from. 'stable' is the stable release, 'nightly' is the latest development build.", "ide.updateChannel": "Canal de publicación desde el que se actualiza. 'stable' es la versión estable, 'nightly' es la última versión de desarrollo.",
"board.certificates": "List of certificates that can be uploaded to boards", "board.certificates": "Listado de certificados que pueden ser cargados en las placas",
"sketchbook.showAllFiles": "True to show all sketch files inside the sketch. It is false by default.", "sketchbook.showAllFiles": "Verdadero para mostrar todos los archivos de bocetos dentro del boceto. Por defecto es falso.",
"cloud.enabled": "Verdadero si la sincronización de código está activada. Valor verdadero por defecto.", "cloud.enabled": "Verdadero si las funciones de sincronización del sketch están activadas. Verdadero por defecto.",
"cloud.pull.warn": "True if users should be warned before pulling a cloud sketch. Defaults to true.", "cloud.pull.warn": "Verdadero si se debe advertir a los usuarios antes de sacar un boceto de la nube. El valor predeterminado es verdadero.",
"cloud.push.warn": "True if users should be warned before pushing a cloud sketch. Defaults to true.", "cloud.push.warn": "Verdadero si se debe advertir a los usuarios antes de enviar un boceto a la nube. El valor predeterminado es verdadero.",
"cloud.pushpublic.warn": "True if users should be warned before pushing a public sketch to the cloud. Defaults to true.", "cloud.pushpublic.warn": "Verdadero si se debe advertir a los usuarios antes de enviar un boceto público a la nube. El valor predeterminado es verdadero.",
"cloud.sketchSyncEnpoint": "The endpoint used to push and pull sketches from a backend. By default it points to Arduino Cloud API.", "cloud.sketchSyncEnpoint": "El punto final utilizado para empujar y extraer bocetos de un backend. Por defecto, apunta a la API de Arduino Cloud.",
"auth.clientID": "The OAuth2 client ID.", "auth.clientID": "El ID del cliente OAuth2.",
"auth.domain": "The OAuth2 domain.", "auth.domain": "El dominio de OAuth2.",
"auth.audience": "The OAuth2 audience.", "auth.audience": "El público de OAuth2.",
"auth.registerUri": "The URI used to register a new user.", "auth.registerUri": "URI usada para registrar un nuevo usuario",
"network": "Red", "network": "Red",
"sketchbook.location": "Sketchbook location", "sketchbook.location": "Ruta del Sketchbook",
"browse": "Explorar", "browse": "Explorar",
"files.inside.sketches": "Show files inside Sketches", "files.inside.sketches": "Ver los ficheros dentro de los bocetos",
"editorFontSize": "Tamaño de letra del editor", "editorFontSize": "Tamaño de letra del editor",
"interfaceScale": "Interface scale", "interfaceScale": "Escala de la interfaz",
"showVerbose": "Show verbose output during", "showVerbose": "Mostrar salida verbosa durante",
"compilerWarnings": "Compiler warnings", "compilerWarnings": "alertas de compilación",
"automatic": "Automático", "automatic": "Automático",
"compile": "Compliar", "compile": "Compliar",
"upload": "Subir", "upload": "Carga",
"verifyAfterUpload": "Verificar código después de subir", "verifyAfterUpload": "Verificar el código después de cargarlo",
"editorQuickSuggestions": "Sugerencias rápidas del editor", "editorQuickSuggestions": "Sugerencias rápidas del editor",
"additionalManagerURLs": "Gestor de URLs Adicionales de Tarjetas", "additionalManagerURLs": "URLs adicionales de gestor de placas",
"noProxy": "No hay proxy", "noProxy": "Sin Proxy",
"manualProxy": "Configuración manual del proxy", "manualProxy": "Configuración manual del proxy",
"newSketchbookLocation": "Select new sketchbook location", "newSketchbookLocation": "Selecciona la nueva ruta del sketchbook",
"choose": "Elija", "choose": "Elija",
"enterAdditionalURLs": "Introduzca otras URLs, una por fila", "enterAdditionalURLs": "Introduzca otras URLs, una por fila",
"unofficialBoardSupport": "Click for a list of unofficial board support URLs", "unofficialBoardSupport": "Pulsa para listar las URLs de las tarjetas no oficiales",
"invalid.sketchbook.location": "Invalid sketchbook location: {0}", "invalid.sketchbook.location": "Ruta del sketchbook no válida: {0}",
"invalid.editorFontSize": "Tamaño de fuente invalido. Debe ser un entero positivo.", "invalid.editorFontSize": "Tamaño de fuente del editor no válido. Debe ser un número entero positivo.",
"invalid.theme": "Tema no valido." "invalid.theme": "Tema no válido."
}, },
"cloud": { "cloud": {
"signIn": "SIGN IN", "signIn": "Iniciar sesión",
"signOut": "Sign Out", "signOut": "Cerrar sesión",
"chooseSketchVisibility": "Choose visibility of your Sketch:", "chooseSketchVisibility": "Elige la visibilidad de tu Sketch:",
"privateVisibility": "Privado: Solo tú puedes ver el código.", "privateVisibility": "Privado: Solo tú puedes ver el código.",
"publicVisibility": "Público: Cualquiera con el enlace puede ver el código.", "publicVisibility": "Público: Cualquiera con el enlace puede ver el código.",
"link": "Enlace:", "link": "Enlace:",
"embed": "Embed:", "embed": "Incrustado:",
"cloudSketchbook": "Cloud Sketchbook", "cloudSketchbook": "Libro de bocetos en la nube",
"shareSketch": "Compartir código", "shareSketch": "Compartir Sketch",
"showHideRemoveSketchbook": "Show/Hide Remote Sketchbook", "showHideRemoveSketchbook": "Mostrar/Ocultar Sketchbook Remoto",
"pullSketch": "Pull Sketch", "pullSketch": "Descargar boceto",
"openInCloudEditor": "Abrir en editor web", "openInCloudEditor": "Abrir en editor web",
"options": "Opciones...", "options": "Opciones...",
"share": "Compartir...", "share": "Compartir...",
"remote": "Remote", "remote": "Remoto",
"emptySketchbook": "Your Sketchbook is empty", "emptySketchbook": "Tu Sketchbook está vacío",
"visitArduinoCloud": "Visit Arduino Cloud to create Cloud Sketches.", "visitArduinoCloud": "Visita Arduino Cloud para crear Cloud Sketches. ",
"signInToCloud": "Sign in to Arduino Cloud", "signInToCloud": "Iniciar sesión en Arduino Cloud",
"syncEditSketches": "Sync and edit your Arduino Cloud Sketches", "syncEditSketches": "Sincroniza y edita tus Arduino Cloud Sketches",
"learnMore": "Learn more", "learnMore": "Aprender más",
"continue": "Continue", "continue": "Continuar",
"pushSketch": "Push Sketch", "pushSketch": "Pulsa para listar las URLs de la tarjetas no oficiales",
"pushSketchMsg": "This is a Public Sketch. Before pushing, make sure any sensitive information is defined in arduino_secrets.h files. You can make a Sketch private from the Share panel.", "pushSketchMsg": "Este es un Sketch público. Antes de enviarlo, asegúrate de que cualquier información sensible está definida en los archivos arduino_secrets.h. Puedes hacer que un Sketch sea privado desde el panel Compartir.",
"pull": "Pull", "pull": "Descargar",
"pullSketchMsg": "Pulling this Sketch from the Cloud will overwrite its local version. Are you sure you want to continue?", "pullSketchMsg": "Descarga finalizada",
"donePulling": "Done pulling {0}.", "donePulling": "Extracción de '{0}' realizada.",
"notYetPulled": "Cannot push to Cloud. It is not yet pulled.", "notYetPulled": "No se puede cargar a las nube. Todavía no ha sido descargado",
"push": "Push", "push": "Cargar",
"pullFirst": "You have to pull first to be able to push to the Cloud.", "pullFirst": "Tiene que descargarlo primero, para poder cargarlo en la nube",
"donePushing": "Done pushing {0}.", "donePushing": "Envío a '{0}' realizado.",
"connected": "Conectado", "connected": "Conectado",
"offline": "Desconectado", "offline": "Desconectado",
"profilePicture": "Foto de perfil" "profilePicture": "Foto de perfil"
}, },
"board": { "board": {
"installManually": "Instalar manualmente", "installManually": "Instalar manualmente",
"installNow": "The \"{0} {1}\" core has to be installed for the currently selected \"{2}\" board. Do you want to install it now?", "installNow": "Hay que instalar el núcleo \"{0} {1} \" para la placa \"{2}\" actualmente seleccionada. ¿Quieres instalarlo ahora?",
"configDialogTitle": "Seleccione otra placa y puerto", "configDialogTitle": "Seleccione otra placa y puerto",
"configDialog1": "Select both a Board and a Port if you want to upload a sketch.", "configDialog1": "Selecciona tanto una placa como un puerto si quieres cargar un sketch.",
"configDialog2": "If you only select a Board you will be able to compile, but not to upload your sketch.", "configDialog2": "Si seleccionas solo una placa podrás compilar, pero no cargar tu sketch.",
"pleasePickBoard": "Por favor, elija una placa conectada al puerto que haya seleccionado.", "pleasePickBoard": "Por favor, elija una placa conectada al puerto que haya seleccionado.",
"showAllAvailablePorts": "Shows all available ports when enabled", "showAllAvailablePorts": "Muestra todos los puertos disponibles cuando está activado",
"programmer": "Programador", "programmer": "Programador",
"succesfullyInstalledPlatform": "Successfully installed platform {0}:{1}", "succesfullyInstalledPlatform": "Plataforma {0}:{1} instalada correctamente",
"succesfullyUninstalledPlatform": "Successfully uninstalled platform {0}:{1}", "succesfullyUninstalledPlatform": "Plataforma {0}:{1} desinstalada correctamente",
"couldNotFindPreviouslySelected": "Could not find previously selected board '{0}' in installed platform '{1}'. Please manually reselect the board you want to use. Do you want to reselect it now?", "couldNotFindPreviouslySelected": "No se ha podido encontrar la placa previamente seleccionada '{0}' en la plataforma instalada '{1}'. Por favor, vuelve a seleccionar manualmente la placa que quieres utilizar. ¿Quieres volver a seleccionarla ahora?",
"reselectLater": "Reselect later", "reselectLater": "Vuelve a seleccionar más tarde",
"noneSelected": "No boards selected.", "noneSelected": "Ninguna placa seleccionada.",
"noPortsSelected": "No ports selected for board: '{0}'.", "noPortsSelected": "No se han seleccionado puertos para la placa: '{0}'.",
"noFQBN": "The FQBN is not available for the selected board \"{0}\". Do you have the corresponding core installed?", "noFQBN": "El FQBN no está disponible para la placa seleccionada \"{0}\". ¿Tienes instalado el núcleo correspondiente?",
"openBoardsConfig": "Seleccione otra placa y puerto...", "openBoardsConfig": "Seleccione otra placa y puerto...",
"boardListItem": "{0} at {1}", "boardListItem": "{0} en {1}",
"selectBoardForInfo": "Por favor, seleccione una placa para obtener información sobre ella.", "selectBoardForInfo": "Por favor, seleccione una placa para obtener información sobre ella.",
"platformMissing": "The platform for the selected '{0}' board is not installed.", "platformMissing": "La plataforma seleccionada para la placa '{0}' no está instalada.",
"selectPortForInfo": "Por favor, seleccione un puerto para obtener información sobre la placa.", "selectPortForInfo": "Por favor, seleccione un puerto para obtener información sobre la placa.",
"boardInfo": "Obtén información de la placa", "boardInfo": "Información de la placa",
"board": "Board{0}", "board": "Placa{0}",
"port": "Port{0}", "port": "Puerto {0}",
"getBoardInfo": "Get Board Info", "getBoardInfo": "Obtener información de la placa",
"inSketchbook": " (in Sketchbook)" "inSketchbook": " (en el Sketchbook)"
}, },
"boardsManager": "Gestor de tarjetas", "boardsManager": "Gestor de placas",
"about": { "about": {
"label": "About {0}", "label": "Acerca de {0}",
"detail": "Version: {0}\nDate: {1}{2}\nCLI Version: {3}{4} [{5}]\n\n{6}" "detail": "Versión: {0}\nFecha: {1}{2}\nVersión del CLI: {3}{4} [{5}]\n\n{6}"
}, },
"contributions": { "contributions": {
"addFile": "Añadir fichero...", "addFile": "Añadir fichero...",
"replaceTitle": "Reemplazar", "replaceTitle": "Reemplazar",
"fileAdded": "One file added to the sketch." "fileAdded": "Un archivo añadido al sketch."
}, },
"replaceMsg": "¿Sustituir la versión existente de {0}?", "replaceMsg": "¿Sustituir la versión existente de {0}?",
"library": { "library": {
"addZip": "Añadir biblioteca .ZIP...", "addZip": "Añadir biblioteca .ZIP...",
"zipLibrary": "Library", "zipLibrary": "Biblioteca",
"overwriteExistingLibrary": "Do you want to overwrite the existing library?", "overwriteExistingLibrary": "¿Quieres sobrescribir la biblioteca existente?",
"successfullyInstalledZipLibrary": "Successfully installed library from {0} archive", "successfullyInstalledZipLibrary": "Biblioteca instalada correctamente desde el archivo {0}",
"namedLibraryAlreadyExists": "A library folder named {0} already exists. Do you want to overwrite it?", "namedLibraryAlreadyExists": "Ya existe una carpeta de la biblioteca llamada {0}. ¿Quieres sobrescribirla?",
"libraryAlreadyExists": "A library already exists. Do you want to overwrite it?", "libraryAlreadyExists": "Ya existe una biblioteca. ¿Quieres sobrescribirla?",
"include": "Include Library", "include": "Incluir biblioteca",
"manageLibraries": "Manage Libraries...", "manageLibraries": "Gestionar bibliotecas...",
"arduinoLibraries": "Arduino libraries", "arduinoLibraries": "Bibliotecas de Arduino",
"contributedLibraries": "Contributed libraries", "contributedLibraries": "Bibliotecas aportadas",
"title": "Library Manager", "title": "Gestor de Bibliotecas",
"needsOneDependency": "The library <b>{0}:{1}</b> needs another dependency currently not installed:", "needsOneDependency": "La biblioteca <b>{0}:{1}</b> necesita otra dependencia que actualmente no está instalada:",
"needsMultipleDependencies": "The library <b>{0}:{1}</b> needs some other dependencies currently not installed:", "needsMultipleDependencies": "La biblioteca <b>{0}:{1}</b> necesita otras dependencias que actualmente no están instaladas:",
"installOneMissingDependency": "Would you like to install the missing dependency?", "installOneMissingDependency": "¿Quieres instalar la dependencia faltante?",
"installMissingDependencies": "Would you like to install all the missing dependencies?", "installMissingDependencies": "¿Quieres instalar todas las dependencias faltantes?",
"dependenciesForLibrary": "Dependencies for library {0}:{1}", "dependenciesForLibrary": "Dependencias para la biblioteca {0}:{1}",
"installAll": "Instalar todo", "installAll": "Instalar todo",
"installOnly": "Instalar {0} solamente", "installOnly": "Instalar {0} solamente",
"installedSuccessfully": "Successfully installed library {0}:{1}", "installedSuccessfully": "Biblioteca {0}:{1} instalada correctamente",
"uninstalledSuccessfully": "Successfully uninstalled library {0}:{1}" "uninstalledSuccessfully": "Biblioteca {0}:{1} desinstalada correctamente"
}, },
"selectZip": "Select a zip file containing the library you'd like to add", "selectZip": "Seleccione un archivo zip que contenga la biblioteca que deseas añadir",
"sketch": { "sketch": {
"archiveSketch": "Archivo de programa", "archiveSketch": "Archivo de programa",
"saveSketchAs": "Save sketch folder as...", "saveSketchAs": "Guardar carpeta de sketch como...",
"createdArchive": "Created archive '{0}'.", "createdArchive": "Archivo '{0}' creado.",
"new": "New", "new": "Nuevo",
"openRecent": "Abierto recientemente", "openRecent": "Abierto recientemente",
"showFolder": "Show Sketch Folder", "showFolder": "Mostrar carpeta de Sketch",
"sketch": "Sketch", "sketch": "Sketch",
"moving": "Moving", "moving": "Moviendo",
"movingMsg": "The file \"{0}\" needs to be inside a sketch folder named \"{1}\".\nCreate this folder, move the file, and continue?", "movingMsg": "El archivo \"{0}\" tiene que estar dentro de una carpeta de bocetos llamada \"{1}\".\n¿Crear esta carpeta, mover el archivo y continuar?",
"cantOpen": "Ya existe una carpeta con el nombre \"{0}\". No se puede abrir.", "cantOpen": "Ya existe una carpeta con el nombre \"{0}\". No se puede abrir.",
"saveFolderAs": "Save sketch folder as...", "saveFolderAs": "Guardar carpeta de sketch como...",
"sketchbook": "Sketchbook", "sketchbook": "Sketchbook",
"upload": "Upload", "upload": "Cargar",
"uploadUsingProgrammer": "Upload Using Programmer", "uploadUsingProgrammer": "Cargar usando el programador",
"userFieldsNotFoundError": "Can't find user fields for connected board", "userFieldsNotFoundError": "No se pueden encontrar campos de usuario para la placa conectada",
"doneUploading": "Done uploading.", "doneUploading": "Carga completada.",
"configureAndUpload": "Configure And Upload", "configureAndUpload": "Configurar y subir",
"verifyOrCompile": "Verify/Compile", "verifyOrCompile": "Verificar/Compilar",
"exportBinary": "Export Compiled Binary", "exportBinary": "Exportar binario compilado",
"verify": "Verify", "verify": "Verificar",
"doneCompiling": "Done compiling.", "doneCompiling": "Compilación completada.",
"couldNotConnectToSerial": "Could not reconnect to serial port. {0}", "couldNotConnectToSerial": "No se ha podido reconectar al puerto serie. {0}",
"openSketchInNewWindow": "Open Sketch in New Window", "openSketchInNewWindow": "Abrir Sketch en una ventana nueva",
"openFolder": "Open Folder", "openFolder": "Abrir carpeta",
"titleLocalSketchbook": "Local Sketchbook", "titleLocalSketchbook": "Sketchbook Local",
"titleSketchbook": "Sketchbook", "titleSketchbook": "Sketchbook",
"close": "Are you sure you want to close the sketch?" "close": "¿Estás seguro de que quieres cerrar el sketch?"
}, },
"bootloader": { "bootloader": {
"burnBootloader": "Quemar Bootloader", "burnBootloader": "Grabar Bootloader",
"doneBurningBootloader": "Done burning bootloader." "doneBurningBootloader": "Finalizada la grabación del bootloader."
}, },
"editor": { "editor": {
"copyForForum": "Copiar al Foro (Markdown)", "copyForForum": "Copiar al Foro (Markdown)",
"commentUncomment": "Comentar / Descomentar", "commentUncomment": "Comentar / Descomentar",
"increaseIndent": "Increase Indent", "increaseIndent": "Aumentar sangría",
"decreaseIndent": "Decrease Indent", "decreaseIndent": "Disminuir sangría",
"increaseFontSize": "Increase Font Size", "increaseFontSize": "Aumentar tamaño de fuente",
"decreaseFontSize": "Reducir Tamaño de Fuente", "decreaseFontSize": "Reducir Tamaño de Fuente",
"autoFormat": "Auto Formato" "autoFormat": "Auto Formato"
}, },
"examples": { "examples": {
"menu": "Examples", "menu": "Ejemplos",
"couldNotInitializeExamples": "Could not initialize built-in examples.", "couldNotInitializeExamples": "No se han podido inicializar los ejemplos integrados.",
"builtInExamples": "Ejemplos Construidos ", "builtInExamples": "Ejemplos Construidos ",
"customLibrary": "Examples from Custom Libraries", "customLibrary": "Ejemplos de bibliotecas personalizadas",
"for": "Examples for {0}", "for": "Ejemplos para {0}",
"forAny": "Examples for any board" "forAny": "Ejemplos para cualquier placa"
}, },
"help": { "help": {
"search": "Search on Arduino.cc", "search": "Buscar en Arduino.cc",
"keyword": "Type a keyword", "keyword": "Escribe una palabra clave",
"gettingStarted": "Getting Started", "gettingStarted": "Primeros pasos",
"environment": "Environment", "environment": "Entorno de desarrollo (IDE)",
"troubleshooting": "Troubleshooting", "troubleshooting": "Resolución de problemas",
"reference": "Reference", "reference": "Referencia",
"findInReference": "Find in Reference", "findInReference": "Buscar en la referencia",
"faq": "Frequently Asked Questions", "faq": "Preguntas frecuentes",
"visit": "Visitar Arduino.cc", "visit": "Visitar Arduino.cc",
"privacyPolicy": "Privacy Policy" "privacyPolicy": "Política de privacidad"
}, },
"certificate": { "certificate": {
"uploadRootCertificates": "Upload SSL Root Certificates", "uploadRootCertificates": "Cargar certificados raíz SSL",
"openContext": "Open context", "openContext": "Contexto abierto",
"remove": "Remove", "remove": "Eliminar",
"upload": "Subir", "upload": "Cargar",
"addURL": "Add URL to fetch SSL certificate", "addURL": "Añadir URL para obtener el certificado SSL",
"enterURL": "Enter URL", "enterURL": "Introduce la URL",
"selectCertificateToUpload": "1. Select certificate to upload", "selectCertificateToUpload": "1. Seleccione el certificado que desea cargar",
"addNew": "Add New", "addNew": "Añadir nuevo",
"selectDestinationBoardToUpload": "2. Select destination board and upload certificate", "selectDestinationBoardToUpload": "2. Seleccione la placa de destino y cargue el certificado",
"uploadingCertificates": "Uploading certificates.", "uploadingCertificates": "Cargando certificados.",
"certificatesUploaded": "Certificates uploaded.", "certificatesUploaded": "Certificados cargados.",
"uploadFailed": "Upload failed. Please try again.", "uploadFailed": "Carga fallida. Por favor, inténtalo de nuevo.",
"selectBoard": "Select a board...", "selectBoard": "Selecciona una placa...",
"boardAtPort": "{0} at {1}", "boardAtPort": "{0} en {1}",
"noSupportedBoardConnected": "No supported board connected" "noSupportedBoardConnected": "No hay ninguna placa compatible conectada"
}, },
"firmware": { "firmware": {
"updater": "WiFi101 / WiFiNINA Firmware Updater", "updater": "Actualizador de Firmware de WiFi101 / WiFiNINA",
"selectBoard": "Select Board", "selectBoard": "Seleccionar Placa",
"checkUpdates": "Check Updates", "checkUpdates": "Comprobar actualizaciones",
"selectVersion": "Select firmware version", "selectVersion": "Seleccionar la versión del firmware",
"install": "Instalar", "install": "Instalar",
"overwriteSketch": "Installation will overwrite the Sketch on the board.", "overwriteSketch": "La instalación sobrescribirá el Sketch de la placa.",
"installingFirmware": "Installing firmware.", "installingFirmware": "Instalando el firmware.",
"successfullyInstalled": "Firmware successfully installed.", "successfullyInstalled": "Firmware instalado correctamente.",
"failedInstall": "Installation failed. Please try again." "failedInstall": "Instalación fallida, Por favor, inténtalo de nuevo."
}, },
"dialog": { "dialog": {
"dontAskAgain": "Don't ask again" "dontAskAgain": "No volver a preguntar"
}, },
"userFields": { "userFields": {
"cancel": "Cancel", "cancel": "Cancelar",
"upload": "Subir" "upload": "Cargar"
}, },
"serial": { "serial": {
"toggleTimestamp": "Toggle Timestamp", "toggleTimestamp": "Alternar la marca de tiempo",
"autoscroll": "Autoscroll", "autoscroll": "Autoscroll",
"timestamp": "Timestamp", "timestamp": "Marca de tiempo",
"noLineEndings": "Sin ajuste de línea", "noLineEndings": "Sin ajuste de línea",
"newLine": "Nueva línea", "newLine": "Nueva línea",
"carriageReturn": "Retorno de carro", "carriageReturn": "Retorno de carro",
"newLineCarriageReturn": "Ambos NL & CR", "newLineCarriageReturn": "Ambos NL & CR",
"notConnected": "Not connected. Select a board and a port to connect automatically.", "notConnected": "No conectado. Selecciona una placa y un puerto para conectarte automáticamente.",
"message": "Message ({0} + Enter to send message to '{1}' on '{2}')", "message": "Mensaje ({0} + Enter para enviar el mensaje a '{1}' en '{2}')",
"connectionBusy": "Connection failed. Serial port is busy: {0}", "connectionBusy": "Error en la conexión. El puerto serie está ocupado: {0}",
"disconnected": "Disconnected {0} from {1}.", "disconnected": "Desconectado {0} de {1}.",
"unexpectedError": "Unexpected error. Reconnecting {0} on port {1}.", "unexpectedError": "Error inesperado. Reconectando {0} en el puerto {1}.",
"failedReconnect": "Failed to reconnect {0} to serial port after 10 consecutive attempts. The {1} serial port is busy.", "failedReconnect": "Fallo al reconectar {0} al puerto serie después de 10 intentos consecutivos. El puerto serie {1} está ocupado.",
"reconnect": "Reconnecting {0} to {1} in {2} seconds..." "reconnect": "Reconectando {0} a {1} en {2} segundos..."
}, },
"component": { "component": {
"uninstall": "Uninstall", "uninstall": "Desinstalar",
"uninstallMsg": "Do you want to uninstall {0}?", "uninstallMsg": "¿Quieres desinstalar {0}?",
"by": "by", "by": "de",
"version": "Versión {0}", "version": "Versión {0}",
"moreInfo": "More info", "moreInfo": "Más información",
"install": "Instalar", "install": "Instalar",
"filterSearch": "Filtre su búsqueda..." "filterSearch": "Filtre su búsqueda..."
}, },
"electron": { "electron": {
"couldNotSave": "Could not save the sketch. Please copy your unsaved work into your favorite text editor, and restart the IDE.", "couldNotSave": "No se ha podido guardar el sketch. Por favor, copia tu trabajo no guardado en tu editor de texto favorito y reinicia el IDE.",
"unsavedChanges": "Any unsaved changes will not be saved." "unsavedChanges": "Los cambios no guardados no serán guardados."
}, },
"compile": { "compile": {
"error": "Compilation error: {0}" "error": "Error de compilación: {0}"
}, },
"upload": { "upload": {
"error": "{0} error: {1}" "error": "1{0} error: 2{1}"
}, },
"burnBootloader": { "burnBootloader": {
"error": "Error while burning the bootloader: {0}" "error": "Error al grabar el bootloader: {0}"
} }
}, },
"theia": { "theia": {
"core": { "core": {
"couldNotSave": "Could not save the sketch. Please copy your unsaved work into your favorite text editor, and restart the IDE.", "couldNotSave": "No se ha podido guardar el sketch. Por favor, copia tu trabajo no guardado en tu editor de texto favorito y reinicia el IDE.",
"offline": "Offline", "offline": "Desconectado",
"daemonOffline": "CLI Daemon Offline", "daemonOffline": "Demonio del CLI fuera de línea",
"cannotConnectBackend": "Cannot connect to the backend.", "cannotConnectBackend": "No se puede conectar al backend.",
"cannotConnectDaemon": "Cannot connect to the CLI daemon." "cannotConnectDaemon": "No se puede conectar con el demonio del CLI."
}, },
"debug": { "debug": {
"start": "Start...", "start": "Empezar...",
"typeNotSupported": "The debug session type \"{0}\" is not supported.", "typeNotSupported": "El tipo de sesión de depuración \"{0}\" no es compatible.",
"startError": "There was an error starting the debug session, check the logs for more details." "startError": "Se ha producido un error al iniciar la sesión de depuración, consulte los logs para obtener más detalles."
}, },
"editor": { "editor": {
"unsavedTitle": "Unsaved {0}" "unsavedTitle": "Sin guardar {0}"
}, },
"messages": { "messages": {
"expand": "Expand", "expand": "Expandir",
"collapse": "Collapse" "collapse": "Contraer"
}, },
"workspace": { "workspace": {
"fileNewName": "Name for new file", "fileNewName": "Nombre del nuevo archivo",
"invalidFilename": "Invalid filename.", "invalidFilename": "Nombre de archivo no válido.",
"invalidExtension": "\".{0}\" no es una extensión válida", "invalidExtension": "\".{0}\" no es una extensión válida",
"newFileName": "New name for file", "newFileName": "Nuevo nombre para el archivo",
"deleteCurrentSketch": "Do you want to delete the current sketch?", "deleteCurrentSketch": "¿Quieres borrar el sketch actual?",
"sketchDirectoryError": "There was an error creating the sketch directory. See the log for more details. The application will probably not work as expected." "sketchDirectoryError": "Se ha producido un error al crear el directorio de bocetos. Consulta el log para obtener más detalles. Es probable que la aplicación no funcione como se espera."
} }
}, },
"cloud": { "cloud": {
"GoToCloud": "GO TO CLOUD" "GoToCloud": "IR AL CLOUD"
} }
} }

View File

@@ -1,350 +1,350 @@
{ {
"arduino": { "arduino": {
"common": { "common": {
"offlineIndicator": "You appear to be offline. Without an Internet connection, the Arduino CLI might not be able to download the required resources and could cause malfunction. Please connect to the Internet and restart the application.", "offlineIndicator": "به نظر می رسد آفلاین هستید. بدون اتصال به اینترنت، رابط ترمینال آردوینو ممکن است نتواند منابع مورد نیاز را دانلود کند و باعث اختلال در عملکرد شود. لطفاً به اینترنت متصل شوید و برنامه را مجدداً راه اندازی کنید.",
"noBoardSelected": "بردی انتخاب نشده", "noBoardSelected": "بردی انتخاب نشده",
"selectedOn": "روشن {0}", "selectedOn": "روشن {0}",
"notConnected": "[not connected]", "notConnected": "[متصل نشد]",
"serialMonitor": "Serial Monitor", "serialMonitor": "نمایشگر ترمینال سریال",
"oldFormat": "The '{0}' still uses the old `.pde` format. Do you want to switch to the new `.ino` extension?", "oldFormat": "'{0}' هنوز از قالب قدیمی `.pde` استفاده می کند. آیا می‌خواهید به برنامه افزودنی «.ino» جدید بروید؟",
"later": "بعدا", "later": "بعدا",
"selectBoard": "انتخاب برد", "selectBoard": "انتخاب برد",
"unknown": "نامعلوم", "unknown": "نامعلوم",
"processing": "در حال محاسبه", "processing": "در حال محاسبه",
"saveChangesToSketch": "Do you want to save changes to this sketch before closing?", "saveChangesToSketch": "آیا می خواهید قبل از بسته شدن، تغییرات را در این طرح ذخیره کنید؟",
"loseChanges": "اگر ذخیره نکنید، تغییراتتون اعمال نمی شوند." "loseChanges": "اگر ذخیره نکنید، تغییراتتون اعمال نمی شوند."
}, },
"ide-updater": { "ide-updater": {
"errorCheckingForUpdates": "Error while checking for Arduino IDE updates.\n{0}", "errorCheckingForUpdates": "خطا در حلقه بررسی برای وجود بروزرسانی برای آردوینو رخ داد. {0}",
"notNowButton": "Not now", "notNowButton": "الان ممکن نیست",
"versionDownloaded": "Arduino IDE {0} has been downloaded.", "versionDownloaded": "آردوینو {0} دانلود شده بوده است.",
"closeToInstallNotice": "Close the software and install the update on your machine.", "closeToInstallNotice": "نرم افزار را ببندید و به روز رسانی را روی دستگاه خود نصب کنید.",
"closeAndInstallButton": "Close and Install", "closeAndInstallButton": "بستن و نصب",
"downloadingNotice": "Downloading the latest version of the Arduino IDE.", "downloadingNotice": "در حال بارگیری آخرین نسخه از آردوینو",
"updateAvailable": "Update Available", "updateAvailable": "به روز رسانی موجود است",
"newVersionAvailable": "A new version of Arduino IDE ({0}) is available for download.", "newVersionAvailable": "ورژن جدید ای دی ای آردوینو ({0}) آماده نصب است.",
"skipVersionButton": "Skip Version", "skipVersionButton": "نسخه بعدی",
"downloadButton": "Download", "downloadButton": "دانلود",
"goToDownloadPage": "An update for the Arduino IDE is available, but we're not able to download and install it automatically. Please go to the download page and download the latest version from there.", "goToDownloadPage": "یک به‌روزرسانی برای آردوینو در دسترس است، اما نمی‌توانیم آن را به‌طور خودکار دانلود و نصب کنیم. لطفا به صفحه دانلود بروید و آخرین نسخه را از آنجا دانلود کنید.",
"goToDownloadButton": "Go To Download", "goToDownloadButton": "برو به بارگیری ",
"ideUpdaterDialog": "Software Update", "ideUpdaterDialog": "به روز رسانی نرم افزار",
"noUpdatesAvailable": "There are no recent updates available for the Arduino IDE" "noUpdatesAvailable": "هیچ به روز رسانی جدیدی برای آردوینو موجود نیست"
}, },
"menu": { "menu": {
"sketch": "Sketch", "sketch": "طرح",
"tools": "ابزار ها" "tools": "ابزار ها"
}, },
"debug": { "debug": {
"optimizeForDebugging": "Optimize for Debugging", "optimizeForDebugging": "بهینه کردن برای رفع خطا",
"debugWithMessage": "Debug - {0}", "debugWithMessage": "رفع خطا {0}",
"noPlatformInstalledFor": "Platform is not installed for '{0}'", "noPlatformInstalledFor": "دستگاه مورد نظر برای {0} نصب نشده است",
"debuggingNotSupported": "Debugging is not supported by '{0}'" "debuggingNotSupported": "رفع خطا توسط {0} پشتیبانی نمی شود."
}, },
"preferences": { "preferences": {
"language.log": "True if the Arduino Language Server should generate log files into the sketch folder. Otherwise, false. It's false by default.", "language.log": "اگر سرور زبان آردوینو باید فایل های گزارش را در پوشه طرح ایجاد کند درست می باشد. در غیر این صورت، نادرست است. به طور پیش فرض نادرست است.",
"compile.verbose": "True for verbose compile output. False by default", "compile.verbose": "برای خروجی کامپایل پرمخاطب درست است. به طور پیش فرض نادرست است",
"compile.warnings": "Tells gcc which warning level to use. It's 'None' by default", "compile.warnings": "به gcc می گوید از کدام سطح هشدار استفاده کند. به طور پیش فرض \"هیچ\" است",
"upload.verbose": "True for verbose upload output. False by default.", "upload.verbose": "برای خروجی آپلود پرمخاطب درست است. به طور پیش فرض نادرست است.",
"window.autoScale": "True if the user interface automatically scales with the font size.", "window.autoScale": "اگر رابط کاربری به طور خودکار با اندازه فونت تغییر کند درست است.",
"window.zoomLevel": "Adjust the zoom level of the window. The original size is 0 and each increment above (e.g. 1) or below (e.g. -1) represents zooming 20% larger or smaller. You can also enter decimals to adjust the zoom level with a finer granularity.", "window.zoomLevel": "سطح بزرگنمایی پنجره را تنظیم کنید. اندازه اصلی 0 است و هر افزایش به بالاتر (مثلاً 1) یا پایین تر (مثلاً -1) نشان دهنده بزرگنمایی 20٪ بزرگتر یا کوچکتر است. همچنین می توانید اعداد اعشاری را وارد کنید تا سطح زوم را با دقت دقیق تر تنظیم کنید.",
"ide.updateChannel": "Release channel to get updated from. 'stable' is the stable release, 'nightly' is the latest development build.", "ide.updateChannel": "برای به روز رسانی کانال را منتشر کنید 'stable' نسخه پایدار است، 'nightly' جدیدترین ساخت توسعه است.",
"board.certificates": "List of certificates that can be uploaded to boards", "board.certificates": "فهرست گواهی‌هایی که می‌توان در تابلوها بارگذاری کرد",
"sketchbook.showAllFiles": "True to show all sketch files inside the sketch. It is false by default.", "sketchbook.showAllFiles": "همه فایل‌های طرح را در داخل طرح نشان دهد درست است. به طور پیش فرض نادرست است.",
"cloud.enabled": "True if the sketch sync functions are enabled. Defaults to true.", "cloud.enabled": "اگر فعال بودن توابع همگام سازی طرح درست می باشد ، پیش فرض ها درست است",
"cloud.pull.warn": "True if users should be warned before pulling a cloud sketch. Defaults to true.", "cloud.pull.warn": "اگر هشدار دادن به کاربران قبل از کشیدن یک طرح ابری درست می باشد ، پیش فرض ها صحیح است.",
"cloud.push.warn": "True if users should be warned before pushing a cloud sketch. Defaults to true.", "cloud.push.warn": "اگر هشدار دادن به کاربران قبل از ارسال یک طرح ابری درست است پیش فرض ها درست می باشد",
"cloud.pushpublic.warn": "True if users should be warned before pushing a public sketch to the cloud. Defaults to true.", "cloud.pushpublic.warn": "اگر هشدار دادن به کاربران قبل از ارسال یک طرح عمومی به فضای درست می باشد پیش فرض ها درست است.",
"cloud.sketchSyncEnpoint": "The endpoint used to push and pull sketches from a backend. By default it points to Arduino Cloud API.", "cloud.sketchSyncEnpoint": "نقطه ای برای ارسال و دریافت طرح ها استفاده می شود . به طور پیش فرض به رابط ابر آردوینو استفاده می کند.",
"auth.clientID": "The OAuth2 client ID.", "auth.clientID": "شناسه مشتری OAuth2(احراز هویت اینترنتی).",
"auth.domain": "The OAuth2 domain.", "auth.domain": "دامنه OAuth2(احراز هویت اینترنتی).",
"auth.audience": "The OAuth2 audience.", "auth.audience": "حضار OAuth2(احراز هویت اینترنتی).",
"auth.registerUri": "The URI used to register a new user.", "auth.registerUri": "لینک برای ثبت یک کاربر جدید استفاده می شود.",
"network": "نتورک", "network": "نتورک",
"sketchbook.location": "Sketchbook location", "sketchbook.location": "مکان منبع طرح ها",
"browse": "Browse", "browse": "مرور کردن",
"files.inside.sketches": "Show files inside Sketches", "files.inside.sketches": "نمایش فایل ها در داخل طرح ها",
"editorFontSize": "Editor font size", "editorFontSize": "اندازه فونت ویرایشگر",
"interfaceScale": "Interface scale", "interfaceScale": "مقیاس رابط",
"showVerbose": "Show verbose output during", "showVerbose": "نمایش خروجی پرمخاطب در طول",
"compilerWarnings": "هشدار های کامپایلر", "compilerWarnings": "هشدار های کامپایلر",
"automatic": "اتوماتیک", "automatic": "اتوماتیک",
"compile": "compile", "compile": "کامپایل",
"upload": "آپلود", "upload": "آپلود",
"verifyAfterUpload": "تائید کد بعد از آپلود", "verifyAfterUpload": "تائید کد بعد از آپلود",
"editorQuickSuggestions": "Editor Quick Suggestions", "editorQuickSuggestions": "پیشنهادات سریع ویرایشگر",
"additionalManagerURLs": "Additional Boards Manager URLs", "additionalManagerURLs": "نشانی‌های اینترنتی مدیر تابلوهای افزوده",
"noProxy": "No proxy", "noProxy": "بدون پروکسی",
"manualProxy": "Manual proxy configuration", "manualProxy": "پیکربندی دستی پروکسی",
"newSketchbookLocation": "Select new sketchbook location", "newSketchbookLocation": "مکان جدید منبع طرح ها را مشخص کنید",
"choose": "انتخاب", "choose": "انتخاب",
"enterAdditionalURLs": "Enter additional URLs, one for each row", "enterAdditionalURLs": "نشانی‌های وب اضافی، یکی برای هر ردیف وارد کنید",
"unofficialBoardSupport": "Click for a list of unofficial board support URLs", "unofficialBoardSupport": "برای لیستی از آدرس های اینترنتی پشتیبانی هیئت مدیره غیررسمی کلیک کنید",
"invalid.sketchbook.location": "Invalid sketchbook location: {0}", "invalid.sketchbook.location": "مکان نامعتبر منبع طرح ها: {0}",
"invalid.editorFontSize": "Invalid editor font size. It must be a positive integer.", "invalid.editorFontSize": "اندازه فونت ویرایشگر نامعتبر است. باید یک عدد صحیح مثبت باشد.",
"invalid.theme": "Invalid theme." "invalid.theme": "طرح زمینه موجود نیست"
}, },
"cloud": { "cloud": {
"signIn": "ورود کاربر", "signIn": "ورود کاربر",
"signOut": "خروج کاربر", "signOut": "خروج کاربر",
"chooseSketchVisibility": "Choose visibility of your Sketch:", "chooseSketchVisibility": "قابلیت مشاهده طرح خود را انتخاب کنید:",
"privateVisibility": "Private. Only you can view the Sketch.", "privateVisibility": "خصوصی است. فقط شما می توانید طرح را مشاهده کنید.",
"publicVisibility": "Public. Anyone with the link can view the Sketch.", "publicVisibility": "عمومی است. هر کسی که پیوند را داشته باشد می تواند طرح را مشاهده کند.",
"link": "لینک:", "link": "لینک:",
"embed": "Embed:", "embed": "قرار دادن:",
"cloudSketchbook": "Cloud Sketchbook", "cloudSketchbook": "منبع ابری طرح ها",
"shareSketch": "اشتراک طرح", "shareSketch": "اشتراک طرح",
"showHideRemoveSketchbook": "Show/Hide Remote Sketchbook", "showHideRemoveSketchbook": "نمایش/پنهان کردن از راه دور منبع طرح ها",
"pullSketch": "Pull Sketch", "pullSketch": "دریافت طرح",
"openInCloudEditor": "در ویرایشگر ابری باز کن", "openInCloudEditor": "در ویرایشگر ابری باز کن",
"options": "تنظیمات...", "options": "تنظیمات...",
"share": "اشتراک گذاری...", "share": "اشتراک گذاری...",
"remote": "Remote", "remote": "از راه دور",
"emptySketchbook": "طرح شما خالی است", "emptySketchbook": "طرح شما خالی است",
"visitArduinoCloud": "Visit Arduino Cloud to create Cloud Sketches.", "visitArduinoCloud": "بازدید از ابر آردوینو برای ساخت ابر طرح ها",
"signInToCloud": "Sign in to Arduino Cloud", "signInToCloud": "ورود به ابر آردوینو",
"syncEditSketches": "Sync and edit your Arduino Cloud Sketches", "syncEditSketches": "طرح های ابر آردوینو خود را همگام سازی و ویرایش کنید",
"learnMore": "Learn more", "learnMore": "یادگیری بیشتر",
"continue": "ادامه", "continue": "ادامه",
"pushSketch": "Push Sketch", "pushSketch": "ارسال طرح",
"pushSketchMsg": "This is a Public Sketch. Before pushing, make sure any sensitive information is defined in arduino_secrets.h files. You can make a Sketch private from the Share panel.", "pushSketchMsg": "این یک طرح عمومی است. قبل از ارسال، مطمئن شوید که اطلاعات حساس در فایل‌های arduino_secrets.h تعریف شده است. می‌توانید از پانل اشتراک‌گذاری یک طرح را خصوصی کنید.",
"pull": "Pull", "pull": "دریافت",
"pullSketchMsg": "Pulling this Sketch from the Cloud will overwrite its local version. Are you sure you want to continue?", "pullSketchMsg": "با بیرون کشیدن این طرح از ابر، نسخه محلی آن بازنویسی می شود. آیا مطمئن هستید که میخواهید ادامه دهید؟",
"donePulling": "Done pulling {0}.", "donePulling": "پایان دریافت {0}",
"notYetPulled": "Cannot push to Cloud. It is not yet pulled.", "notYetPulled": "نمی توان به ابر ارسال کرد. هنوز دریافت نشده است.",
"push": "Push", "push": "ارسال",
"pullFirst": "You have to pull first to be able to push to the Cloud.", "pullFirst": "ابتدا باید دریافت کنید تا بتوانید به سمت ابر ارسال کنید.",
"donePushing": "Done pushing {0}.", "donePushing": "پایان ارسال {0}",
"connected": "متصل", "connected": "متصل",
"offline": "آفلاین", "offline": "آفلاین",
"profilePicture": "عکس پروفایل" "profilePicture": "عکس پروفایل"
}, },
"board": { "board": {
"installManually": "دستی نصب کن", "installManually": "دستی نصب کن",
"installNow": "The \"{0} {1}\" core has to be installed for the currently selected \"{2}\" board. Do you want to install it now?", "installNow": "هسته \"{0}{1}\" باید برای برد \"{2}\" انتخاب شده فعلی نصب شود. آیا الان می خواهید نصبش کنید؟",
"configDialogTitle": "انتخاب یک بورد و پورت دیگر", "configDialogTitle": "انتخاب یک بورد و پورت دیگر",
"configDialog1": "Select both a Board and a Port if you want to upload a sketch.", "configDialog1": "اگر می‌خواهید طرحی را آپلود کنید، هم یک تابلو و هم یک پورت انتخاب کنید.",
"configDialog2": "If you only select a Board you will be able to compile, but not to upload your sketch.", "configDialog2": "اگر فقط تابلو را انتخاب کنید، می توانید کامپایل کنید، اما نمی توانید طرح خود را آپلود کنید.",
"pleasePickBoard": "Please pick a board connected to the port you have selected.", "pleasePickBoard": "لطفاً یک برد متصل به پورتی که انتخاب کرده اید را انتخاب کنید.",
"showAllAvailablePorts": "Shows all available ports when enabled", "showAllAvailablePorts": "نمایش تمام پورت های موجود در صورت فعال بودن",
"programmer": "برنامه ریز", "programmer": "برنامه ریز",
"succesfullyInstalledPlatform": "Successfully installed platform {0}:{1}", "succesfullyInstalledPlatform": "نصب پلتفرم موفقیت آمیز بود {0}:{1}",
"succesfullyUninstalledPlatform": "Successfully uninstalled platform {0}:{1}", "succesfullyUninstalledPlatform": "لغو نصب پلتفرم موفقیت آمیز بود. {0}:{1}",
"couldNotFindPreviouslySelected": "Could not find previously selected board '{0}' in installed platform '{1}'. Please manually reselect the board you want to use. Do you want to reselect it now?", "couldNotFindPreviouslySelected": "نمی توان برد انتخاب شده قبلی '{0}' در پلتفرم نصب شده '{1}' را پیدا کرد. لطفاً تابلویی را که می‌خواهید استفاده کنید، مجدداً به‌صورت دستی انتخاب کنید. آیا اکنون می خواهید آن را مجدداً انتخاب کنید؟",
"reselectLater": "بعدا انتخاب کنید", "reselectLater": "بعدا انتخاب کنید",
"noneSelected": "No boards selected.", "noneSelected": "هیچ بردی انتخاب نشده است.",
"noPortsSelected": "No ports selected for board: '{0}'.", "noPortsSelected": "هیچ پورتی برای برد انتخاب نشده است.{0}",
"noFQBN": "The FQBN is not available for the selected board \"{0}\". Do you have the corresponding core installed?", "noFQBN": "FQBN برای برد انتخاب شده \"{0}\" موجود نیست. آیا هسته مربوطه را نصب کرده اید؟",
"openBoardsConfig": "Select other board and port…", "openBoardsConfig": "انتخاب سایر برد ها و پورت ها",
"boardListItem": "{0} در {1}", "boardListItem": "{0} در {1}",
"selectBoardForInfo": "Please select a board to obtain board info.", "selectBoardForInfo": "لطفاً یک برد را برای به دست آوردن اطلاعات هیئت مدیره انتخاب کنید.",
"platformMissing": "The platform for the selected '{0}' board is not installed.", "platformMissing": "پلت فرم برای برد انتخابی '{0}' نصب نشده است.",
"selectPortForInfo": "Please select a port to obtain board info.", "selectPortForInfo": "لطفاً یک پورت را برای به دست آوردن اطلاعات هیئت مدیره انتخاب کنید.",
"boardInfo": "مشخصات برد", "boardInfo": "مشخصات برد",
"board": "بورد {0}", "board": "بورد {0}",
"port": "پورت {0}", "port": "پورت {0}",
"getBoardInfo": "Get Board Info", "getBoardInfo": "دریافت راهنمای برد",
"inSketchbook": " (in Sketchbook)" "inSketchbook": "(در منبع طرح ها)"
}, },
"boardsManager": "Boards Manager", "boardsManager": "مدیریت برد ها",
"about": { "about": {
"label": "درباره {0}", "label": "درباره {0}",
"detail": "Version: {0}\nDate: {1}{2}\nCLI Version: {3}{4} [{5}]\n\n{6}" "detail": "نسخه :{0}\nتاریخ: {1} {2}\nنسخه CLI : {3}{4} [{5}]\n\n{6}"
}, },
"contributions": { "contributions": {
"addFile": "فایل اظافه کن", "addFile": "فایل اظافه کن",
"replaceTitle": "جایگذاری", "replaceTitle": "جایگذاری",
"fileAdded": "One file added to the sketch." "fileAdded": "یک فایل به طرح افزوده شد."
}, },
"replaceMsg": "Replace the existing version of {0}?", "replaceMsg": "آیا می خواهید نسخه موجود را با {0} جایگزین کنید؟",
"library": { "library": {
"addZip": "اضافه کتابخانه ی .zip شده", "addZip": "اضافه کتابخانه ی .zip شده",
"zipLibrary": "کتابخانه", "zipLibrary": "کتابخانه",
"overwriteExistingLibrary": "Do you want to overwrite the existing library?", "overwriteExistingLibrary": "آیا می خواهید کتابخانه موجود را بازنویسی کنید؟",
"successfullyInstalledZipLibrary": "Successfully installed library from {0} archive", "successfullyInstalledZipLibrary": "نصب کتابخانه از {0} موفقیت امیز بود.",
"namedLibraryAlreadyExists": "A library folder named {0} already exists. Do you want to overwrite it?", "namedLibraryAlreadyExists": "یک پوشه کتابخانه به نام {0} از قبل وجود دارد. آیا می خواهید آن را بازنویسی کنید؟",
"libraryAlreadyExists": "A library already exists. Do you want to overwrite it?", "libraryAlreadyExists": "یک کتابخانه از قبل وجود دارد. آیا میخواهید آن را بازنویسی کنید؟",
"include": "اضافه کتابخانه", "include": "اضافه کتابخانه",
"manageLibraries": "مدیریت کتابخانه ها...", "manageLibraries": "مدیریت کتابخانه ها...",
"arduinoLibraries": "کتابخانه های آردوینو", "arduinoLibraries": "کتابخانه های آردوینو",
"contributedLibraries": "Contributed libraries", "contributedLibraries": "کتابخانه های اشتراکی",
"title": "اداره کتابخانه ها", "title": "اداره کتابخانه ها",
"needsOneDependency": "The library <b>{0}:{1}</b> needs another dependency currently not installed:", "needsOneDependency": "کتابخانه <b>{0}:{1}</b> به وابستگی دیگری نیاز دارد که در حال حاضر نصب نشده است:",
"needsMultipleDependencies": "The library <b>{0}:{1}</b> needs some other dependencies currently not installed:", "needsMultipleDependencies": "کتابخانه <b>{0}:{1}</b> به برخی وابستگی های دیگر نیاز دارد که در حال حاضر نصب نشده اند:",
"installOneMissingDependency": "Would you like to install the missing dependency?", "installOneMissingDependency": "آیا می خواهید وابستگی از دست رفته را نصب کنید؟",
"installMissingDependencies": "Would you like to install all the missing dependencies?", "installMissingDependencies": "آیا می خواهید تمام وابستگی های از دست رفته را نصب کنید؟",
"dependenciesForLibrary": "Dependencies for library {0}:{1}", "dependenciesForLibrary": "وابستگی های کتابخانه {0}:{1}",
"installAll": "نصب همه", "installAll": "نصب همه",
"installOnly": "فقط {0} را نصب کن", "installOnly": "فقط {0} را نصب کن",
"installedSuccessfully": "Successfully installed library {0}:{1}", "installedSuccessfully": "نصب کتابخانه {0}:{1} موفقیت آمیز بود.",
"uninstalledSuccessfully": "Successfully uninstalled library {0}:{1}" "uninstalledSuccessfully": "لغو نصب کتابخانه {0}:{1} موفقیت آمیز بود."
}, },
"selectZip": "Select a zip file containing the library you'd like to add", "selectZip": "یک فایل فشرده حاوی کتابخانه ای را که می خواهید اضافه کنید انتخاب کنید",
"sketch": { "sketch": {
"archiveSketch": "آرشیو طرح", "archiveSketch": "آرشیو طرح",
"saveSketchAs": "Save sketch folder as...", "saveSketchAs": "ذخیره پوشه طرح در ...",
"createdArchive": "Created archive '{0}'.", "createdArchive": "آرشیو {0} ایجاد شد.",
"new": "جدید", "new": "جدید",
"openRecent": "باز کردن آخرین ها", "openRecent": "باز کردن آخرین ها",
"showFolder": "Show Sketch Folder", "showFolder": "نمایش پوشه ظرح",
"sketch": "طرح", "sketch": "طرح",
"moving": "Moving", "moving": "جابجا کردن",
"movingMsg": "The file \"{0}\" needs to be inside a sketch folder named \"{1}\".\nCreate this folder, move the file, and continue?", "movingMsg": "فایل \"{0}\" باید داخل یک پوشه طرح به نام \"{1}\" باشد.\nاین پوشه را ایجاد کنید، فایل را منتقل کنید و ادامه دهید؟",
"cantOpen": "A folder named \"{0}\" already exists. Can't open sketch.", "cantOpen": "پوشه ای با نام \"{0}\" از قبل وجود دارد. طرح را نمی توان باز کرد",
"saveFolderAs": "Save sketch folder as...", "saveFolderAs": "ذخیره پوشه طرح در ...",
"sketchbook": "Sketchbook", "sketchbook": "منبع طرح ها",
"upload": "آپلود", "upload": "آپلود",
"uploadUsingProgrammer": "Upload Using Programmer", "uploadUsingProgrammer": "بارگذاری با استفاده از پروگرامر",
"userFieldsNotFoundError": "Can't find user fields for connected board", "userFieldsNotFoundError": "عدم یافت شدن فیلد های کاربر برای برد متصل",
"doneUploading": "Done uploading.", "doneUploading": "پایان بارگذاری",
"configureAndUpload": "Configure And Upload", "configureAndUpload": "پیکربندی و بارگذاری",
"verifyOrCompile": "Verify/Compile", "verifyOrCompile": "تائید / کامپایل",
"exportBinary": "Export Compiled Binary", "exportBinary": "دریافت خروجی باینری کامپایل شده",
"verify": "Verify", "verify": "تائید",
"doneCompiling": "Done compiling.", "doneCompiling": "پایان کامپایل کردن",
"couldNotConnectToSerial": "Could not reconnect to serial port. {0}", "couldNotConnectToSerial": "ابر نتوانست دوباره به پورت سریال {0} متصل شود.",
"openSketchInNewWindow": "Open Sketch in New Window", "openSketchInNewWindow": "باز کردن طرح در پنجره جدید.",
"openFolder": "Open Folder", "openFolder": "بازکردن پوشه",
"titleLocalSketchbook": "Local Sketchbook", "titleLocalSketchbook": "منبع طرح محلی",
"titleSketchbook": "Sketchbook", "titleSketchbook": "منبع طرح ها",
"close": "Are you sure you want to close the sketch?" "close": "آیا شما می خواهید این طرح را ببندید؟"
}, },
"bootloader": { "bootloader": {
"burnBootloader": "Burn Bootloader", "burnBootloader": "بارگذاری بوت لودر.",
"doneBurningBootloader": "Done burning bootloader." "doneBurningBootloader": "اتمام بارگذاری بوت لودر."
}, },
"editor": { "editor": {
"copyForForum": "Copy for Forum (Markdown)", "copyForForum": "کپی از انجمن (Markdown)",
"commentUncomment": "Comment/Uncomment", "commentUncomment": "نظر / لغو نظر",
"increaseIndent": "Increase Indent", "increaseIndent": "افزودن دندانه",
"decreaseIndent": "Decrease Indent", "decreaseIndent": "برداشتن دندانه",
"increaseFontSize": "Increase Font Size", "increaseFontSize": "افزایش اندازه فونت",
"decreaseFontSize": "Decrease Font Size", "decreaseFontSize": "کاهش اندازه فونت",
"autoFormat": "Auto Format" "autoFormat": "دندانه گذاری خودکار"
}, },
"examples": { "examples": {
"menu": "Examples", "menu": "مثال ها",
"couldNotInitializeExamples": "Could not initialize built-in examples.", "couldNotInitializeExamples": "ابر نمی تواند نمونه های داخلی را مقدار دهی اولیه کند.",
"builtInExamples": "Built-in examples", "builtInExamples": "نمونه های داخلی",
"customLibrary": "Examples from Custom Libraries", "customLibrary": "مثال از کتابخانه شخصی",
"for": "Examples for {0}", "for": "مثال برای {0}",
"forAny": "Examples for any board" "forAny": "مثال برای همه برد ها"
}, },
"help": { "help": {
"search": "Search on Arduino.cc", "search": "جستجو در Arduino.cc",
"keyword": "Type a keyword", "keyword": "کلید واژه را بنویسید",
"gettingStarted": "Getting Started", "gettingStarted": "آغاز کار",
"environment": "Environment", "environment": "محیط",
"troubleshooting": "Troubleshooting", "troubleshooting": "عیب یابی",
"reference": "Reference", "reference": "دستورالعمل",
"findInReference": "Find in Reference", "findInReference": "جستجو در دستورالعمل",
"faq": "Frequently Asked Questions", "faq": "سوالات سریع پاسخ داده شده",
"visit": "Visit Arduino.cc", "visit": "بازدید از Arduino.cc",
"privacyPolicy": "Privacy Policy" "privacyPolicy": "حریم خصوصی"
}, },
"certificate": { "certificate": {
"uploadRootCertificates": "Upload SSL Root Certificates", "uploadRootCertificates": "بارگذاری سند ریشه SSL",
"openContext": "Open context", "openContext": "زمینه باز",
"remove": "Remove", "remove": "حذف",
"upload": "آپلود", "upload": "آپلود",
"addURL": "Add URL to fetch SSL certificate", "addURL": "افزودن لینک به سند واکشی SSL",
"enterURL": "Enter URL", "enterURL": "لینک را بنویسید.",
"selectCertificateToUpload": "1. Select certificate to upload", "selectCertificateToUpload": "1. انتخاب سند برای بارگذاری",
"addNew": "Add New", "addNew": "افزودن جدید",
"selectDestinationBoardToUpload": "2. Select destination board and upload certificate", "selectDestinationBoardToUpload": "2. انتخاب برد مورد نظر و بارگذاری سند",
"uploadingCertificates": "Uploading certificates.", "uploadingCertificates": "در حال بارگذاری سند.",
"certificatesUploaded": "Certificates uploaded.", "certificatesUploaded": "سند بارگذاری شد.",
"uploadFailed": "آپلود ناموفق بود. لطفا دوباره سعی کنید.", "uploadFailed": "آپلود ناموفق بود. لطفا دوباره سعی کنید.",
"selectBoard": "Select a board...", "selectBoard": "انتخاب یک برد ...",
"boardAtPort": "{0} at {1}", "boardAtPort": "{0} در {1}",
"noSupportedBoardConnected": "No supported board connected" "noSupportedBoardConnected": "برد متصل شده پشتیبانی نمی شود."
}, },
"firmware": { "firmware": {
"updater": "WiFi101 / WiFiNINA Firmware Updater", "updater": "بروزرسان درایور WiFi101 / WiFiNINA",
"selectBoard": "Select Board", "selectBoard": "انتخاب برد",
"checkUpdates": "Check Updates", "checkUpdates": "بررسی بروزرسانی",
"selectVersion": "Select firmware version", "selectVersion": "انتخاب نسخه درایور",
"install": "نصب", "install": "نصب",
"overwriteSketch": "Installation will overwrite the Sketch on the board.", "overwriteSketch": "نصب کردن، طرح را روی برد بازنویسی می کند.",
"installingFirmware": "Installing firmware.", "installingFirmware": "در حال نصب درایور.",
"successfullyInstalled": "Firmware successfully installed.", "successfullyInstalled": "نصب درایور موفقیت آمیز بود.",
"failedInstall": "Installation failed. Please try again." "failedInstall": "نصب ناموفق بود. دوباره تلاش کنید."
}, },
"dialog": { "dialog": {
"dontAskAgain": "Don't ask again" "dontAskAgain": "نمی تواند بپرسد."
}, },
"userFields": { "userFields": {
"cancel": "لغو", "cancel": "لغو",
"upload": "Upload" "upload": "بارگذاری"
}, },
"serial": { "serial": {
"toggleTimestamp": "Toggle Timestamp", "toggleTimestamp": "اتصال برچسب زمان",
"autoscroll": "Autoscroll", "autoscroll": "پیمایش خودکار",
"timestamp": "Timestamp", "timestamp": "برچسب زمانی",
"noLineEndings": "No Line Ending", "noLineEndings": "بدون پایان خط",
"newLine": "New Line", "newLine": "خط جدید",
"carriageReturn": "Carriage Return", "carriageReturn": "رفتن به سر سطر",
"newLineCarriageReturn": "Both NL & CR", "newLineCarriageReturn": "هم NL و هم CR",
"notConnected": "Not connected. Select a board and a port to connect automatically.", "notConnected": "متصل نشد. برد و پورت را انتخاب کنید تا بطور خودکار متصل شود.",
"message": "Message ({0} + Enter to send message to '{1}' on '{2}')", "message": "پیام ( {0} + بزنید تا پیام به '{1}' بر '{2}' ارسال شود)",
"connectionBusy": "Connection failed. Serial port is busy: {0}", "connectionBusy": "اتصال ناموفق بود. پورت سریال مشغول به {0} است.",
"disconnected": "Disconnected {0} from {1}.", "disconnected": "{0} از {1} قطع شد.",
"unexpectedError": "Unexpected error. Reconnecting {0} on port {1}.", "unexpectedError": "خطای غیر منتظره. اتصال مجدد {0} در پورت {1}.",
"failedReconnect": "Failed to reconnect {0} to serial port after 10 consecutive attempts. The {1} serial port is busy.", "failedReconnect": "اتصال دوباره {0} به پورت سریال بعد از 10 تلاش متوالی ناموفق بود. {1} پورت سریال مشغول است.",
"reconnect": "Reconnecting {0} to {1} in {2} seconds..." "reconnect": "اتصال دوباره {0} به {1} در {2} ثانیه ..."
}, },
"component": { "component": {
"uninstall": "Uninstall", "uninstall": "لغو نصب",
"uninstallMsg": "Do you want to uninstall {0}?", "uninstallMsg": "آیا شما می خواهید {0} را لغو نصب کنید؟",
"by": "by", "by": "توسط",
"version": "ورژن {0}", "version": "ورژن {0}",
"moreInfo": "اطلاعات بیشتر", "moreInfo": "اطلاعات بیشتر",
"install": "نصب", "install": "نصب",
"filterSearch": "Filter your search..." "filterSearch": "محدود کردن جستجوی شما ..."
}, },
"electron": { "electron": {
"couldNotSave": "Could not save the sketch. Please copy your unsaved work into your favorite text editor, and restart the IDE.", "couldNotSave": "ابر طرح را ذخیره نکرد. لطفا کار ذخیره نشده خود را به ویرایشگر متن مورد علاقه خود کپی کنید، و آردوینو را دوباره راه اندازی کنید.",
"unsavedChanges": "Any unsaved changes will not be saved." "unsavedChanges": "هر تغییری که انجام می دهید ذخیره نمی شود."
}, },
"compile": { "compile": {
"error": "Compilation error: {0}" "error": "خطای کامپایل : {0}"
}, },
"upload": { "upload": {
"error": "{0} error: {1}" "error": "خطا {0} : {1}"
}, },
"burnBootloader": { "burnBootloader": {
"error": "Error while burning the bootloader: {0}" "error": "خطای حیاتی حلقه بوت لودر : {0}"
} }
}, },
"theia": { "theia": {
"core": { "core": {
"couldNotSave": "Could not save the sketch. Please copy your unsaved work into your favorite text editor, and restart the IDE.", "couldNotSave": "ابر طرح را ذخیره نکرد. لطفا کار ذخیره نشده خود را به ویرایشگر متن مورد علاقه خود کپی کنید، و آردوینو را دوباره راه اندازی کنید.",
"offline": "Offline", "offline": "آفلاین",
"daemonOffline": "CLI Daemon Offline", "daemonOffline": "CLI آفلاین پس زمینه",
"cannotConnectBackend": "Cannot connect to the backend.", "cannotConnectBackend": "اتصال به سرور ناموفق بود.",
"cannotConnectDaemon": "Cannot connect to the CLI daemon." "cannotConnectDaemon": "نمی توان به CLI پس زمینه متصل شد."
}, },
"debug": { "debug": {
"start": "Start...", "start": "شروع...",
"typeNotSupported": "The debug session type \"{0}\" is not supported.", "typeNotSupported": "جلسه رفع خطا \"{0}\" پشتیبانی نمی شود.",
"startError": "There was an error starting the debug session, check the logs for more details." "startError": "یک خطا در آغاز جلسه رفع خطا بود، تاریخچه بقیه جزئیات را بررسی کنید."
}, },
"editor": { "editor": {
"unsavedTitle": "Unsaved {0}" "unsavedTitle": "ذخیره نشده {0}"
}, },
"messages": { "messages": {
"expand": "Expand", "expand": "باز کردن.",
"collapse": "Collapse" "collapse": "فروکش"
}, },
"workspace": { "workspace": {
"fileNewName": "Name for new file", "fileNewName": "نام برای فایل جدید",
"invalidFilename": "Invalid filename.", "invalidFilename": "عدم وجود نام برای فایل",
"invalidExtension": ".{0} is not a valid extension", "invalidExtension": "افزونه {0} نادرست است.",
"newFileName": "New name for file", "newFileName": "نام جدید برای فایل",
"deleteCurrentSketch": "Do you want to delete the current sketch?", "deleteCurrentSketch": "آیا می خواهید طرح کنونی را حذف کنید؟",
"sketchDirectoryError": "There was an error creating the sketch directory. See the log for more details. The application will probably not work as expected." "sketchDirectoryError": "یک خطا در ساخت دیکشنری طرح بود، تاریخچه بقیه جزئیات را بررسی کنید. نرم افزار شاید نتواند پیش بینی شده کار کند."
} }
}, },
"cloud": { "cloud": {
"GoToCloud": "GO TO CLOUD" "GoToCloud": "برو به ابر"
} }
} }

View File

@@ -16,18 +16,18 @@
}, },
"ide-updater": { "ide-updater": {
"errorCheckingForUpdates": "Error while checking for Arduino IDE updates.\n{0}", "errorCheckingForUpdates": "Error while checking for Arduino IDE updates.\n{0}",
"notNowButton": "Not now", "notNowButton": "לא עכשיו",
"versionDownloaded": "Arduino IDE {0} has been downloaded.", "versionDownloaded": "Arduino IDE {0} has been downloaded.",
"closeToInstallNotice": "Close the software and install the update on your machine.", "closeToInstallNotice": "סגור את התוכנה והתקן את העדכון על המכונה שלך.",
"closeAndInstallButton": "Close and Install", "closeAndInstallButton": "סגור והתקן",
"downloadingNotice": "Downloading the latest version of the Arduino IDE.", "downloadingNotice": "Downloading the latest version of the Arduino IDE.",
"updateAvailable": "Update Available", "updateAvailable": "נמצא עדכון",
"newVersionAvailable": "A new version of Arduino IDE ({0}) is available for download.", "newVersionAvailable": "A new version of Arduino IDE ({0}) is available for download.",
"skipVersionButton": "Skip Version", "skipVersionButton": "דלג גרסה",
"downloadButton": "Download", "downloadButton": "הורד",
"goToDownloadPage": "An update for the Arduino IDE is available, but we're not able to download and install it automatically. Please go to the download page and download the latest version from there.", "goToDownloadPage": "An update for the Arduino IDE is available, but we're not able to download and install it automatically. Please go to the download page and download the latest version from there.",
"goToDownloadButton": "Go To Download", "goToDownloadButton": "Go To Download",
"ideUpdaterDialog": "Software Update", "ideUpdaterDialog": "עדכון תוכנה",
"noUpdatesAvailable": "There are no recent updates available for the Arduino IDE" "noUpdatesAvailable": "There are no recent updates available for the Arduino IDE"
}, },
"menu": { "menu": {

350
i18n/hi.json Normal file
View File

@@ -0,0 +1,350 @@
{
"arduino": {
"common": {
"offlineIndicator": "You appear to be offline. Without an Internet connection, the Arduino CLI might not be able to download the required resources and could cause malfunction. Please connect to the Internet and restart the application.",
"noBoardSelected": "No board selected",
"selectedOn": "on {0}",
"notConnected": "[not connected]",
"serialMonitor": "Serial Monitor",
"oldFormat": "The '{0}' still uses the old `.pde` format. Do you want to switch to the new `.ino` extension?",
"later": "Later",
"selectBoard": "Select Board",
"unknown": "Unknown",
"processing": "Processing",
"saveChangesToSketch": "Do you want to save changes to this sketch before closing?",
"loseChanges": "If you don't save, your changes will be lost."
},
"ide-updater": {
"errorCheckingForUpdates": "Error while checking for Arduino IDE updates.\n{0}",
"notNowButton": "Not now",
"versionDownloaded": "Arduino IDE {0} has been downloaded.",
"closeToInstallNotice": "Close the software and install the update on your machine.",
"closeAndInstallButton": "Close and Install",
"downloadingNotice": "Downloading the latest version of the Arduino IDE.",
"updateAvailable": "Update Available",
"newVersionAvailable": "A new version of Arduino IDE ({0}) is available for download.",
"skipVersionButton": "Skip Version",
"downloadButton": "Download",
"goToDownloadPage": "An update for the Arduino IDE is available, but we're not able to download and install it automatically. Please go to the download page and download the latest version from there.",
"goToDownloadButton": "Go To Download",
"ideUpdaterDialog": "Software Update",
"noUpdatesAvailable": "There are no recent updates available for the Arduino IDE"
},
"menu": {
"sketch": "Sketch",
"tools": "Tools"
},
"debug": {
"optimizeForDebugging": "Optimize for Debugging",
"debugWithMessage": "Debug - {0}",
"noPlatformInstalledFor": "Platform is not installed for '{0}'",
"debuggingNotSupported": "Debugging is not supported by '{0}'"
},
"preferences": {
"language.log": "True if the Arduino Language Server should generate log files into the sketch folder. Otherwise, false. It's false by default.",
"compile.verbose": "True for verbose compile output. False by default",
"compile.warnings": "Tells gcc which warning level to use. It's 'None' by default",
"upload.verbose": "True for verbose upload output. False by default.",
"window.autoScale": "True if the user interface automatically scales with the font size.",
"window.zoomLevel": "Adjust the zoom level of the window. The original size is 0 and each increment above (e.g. 1) or below (e.g. -1) represents zooming 20% larger or smaller. You can also enter decimals to adjust the zoom level with a finer granularity.",
"ide.updateChannel": "Release channel to get updated from. 'stable' is the stable release, 'nightly' is the latest development build.",
"board.certificates": "List of certificates that can be uploaded to boards",
"sketchbook.showAllFiles": "True to show all sketch files inside the sketch. It is false by default.",
"cloud.enabled": "True if the sketch sync functions are enabled. Defaults to true.",
"cloud.pull.warn": "True if users should be warned before pulling a cloud sketch. Defaults to true.",
"cloud.push.warn": "True if users should be warned before pushing a cloud sketch. Defaults to true.",
"cloud.pushpublic.warn": "True if users should be warned before pushing a public sketch to the cloud. Defaults to true.",
"cloud.sketchSyncEnpoint": "The endpoint used to push and pull sketches from a backend. By default it points to Arduino Cloud API.",
"auth.clientID": "The OAuth2 client ID.",
"auth.domain": "The OAuth2 domain.",
"auth.audience": "The OAuth2 audience.",
"auth.registerUri": "The URI used to register a new user.",
"network": "Network",
"sketchbook.location": "Sketchbook location",
"browse": "Browse",
"files.inside.sketches": "Show files inside Sketches",
"editorFontSize": "Editor font size",
"interfaceScale": "Interface scale",
"showVerbose": "Show verbose output during",
"compilerWarnings": "Compiler warnings",
"automatic": "Automatic",
"compile": "compile",
"upload": "upload",
"verifyAfterUpload": "Verify code after upload",
"editorQuickSuggestions": "Editor Quick Suggestions",
"additionalManagerURLs": "Additional Boards Manager URLs",
"noProxy": "No proxy",
"manualProxy": "Manual proxy configuration",
"newSketchbookLocation": "Select new sketchbook location",
"choose": "Choose",
"enterAdditionalURLs": "Enter additional URLs, one for each row",
"unofficialBoardSupport": "Click for a list of unofficial board support URLs",
"invalid.sketchbook.location": "Invalid sketchbook location: {0}",
"invalid.editorFontSize": "Invalid editor font size. It must be a positive integer.",
"invalid.theme": "Invalid theme."
},
"cloud": {
"signIn": "SIGN IN",
"signOut": "Sign Out",
"chooseSketchVisibility": "Choose visibility of your Sketch:",
"privateVisibility": "Private. Only you can view the Sketch.",
"publicVisibility": "Public. Anyone with the link can view the Sketch.",
"link": "Link:",
"embed": "Embed:",
"cloudSketchbook": "Cloud Sketchbook",
"shareSketch": "Share Sketch",
"showHideRemoveSketchbook": "Show/Hide Remote Sketchbook",
"pullSketch": "Pull Sketch",
"openInCloudEditor": "Open in Cloud Editor",
"options": "Options...",
"share": "Share...",
"remote": "Remote",
"emptySketchbook": "Your Sketchbook is empty",
"visitArduinoCloud": "Visit Arduino Cloud to create Cloud Sketches.",
"signInToCloud": "Sign in to Arduino Cloud",
"syncEditSketches": "Sync and edit your Arduino Cloud Sketches",
"learnMore": "Learn more",
"continue": "Continue",
"pushSketch": "Push Sketch",
"pushSketchMsg": "This is a Public Sketch. Before pushing, make sure any sensitive information is defined in arduino_secrets.h files. You can make a Sketch private from the Share panel.",
"pull": "Pull",
"pullSketchMsg": "Pulling this Sketch from the Cloud will overwrite its local version. Are you sure you want to continue?",
"donePulling": "Done pulling {0}.",
"notYetPulled": "Cannot push to Cloud. It is not yet pulled.",
"push": "Push",
"pullFirst": "You have to pull first to be able to push to the Cloud.",
"donePushing": "Done pushing {0}.",
"connected": "Connected",
"offline": "Offline",
"profilePicture": "Profile picture"
},
"board": {
"installManually": "Install Manually",
"installNow": "The \"{0} {1}\" core has to be installed for the currently selected \"{2}\" board. Do you want to install it now?",
"configDialogTitle": "Select Other Board & Port",
"configDialog1": "Select both a Board and a Port if you want to upload a sketch.",
"configDialog2": "If you only select a Board you will be able to compile, but not to upload your sketch.",
"pleasePickBoard": "Please pick a board connected to the port you have selected.",
"showAllAvailablePorts": "Shows all available ports when enabled",
"programmer": "Programmer",
"succesfullyInstalledPlatform": "Successfully installed platform {0}:{1}",
"succesfullyUninstalledPlatform": "Successfully uninstalled platform {0}:{1}",
"couldNotFindPreviouslySelected": "Could not find previously selected board '{0}' in installed platform '{1}'. Please manually reselect the board you want to use. Do you want to reselect it now?",
"reselectLater": "Reselect later",
"noneSelected": "No boards selected.",
"noPortsSelected": "No ports selected for board: '{0}'.",
"noFQBN": "The FQBN is not available for the selected board \"{0}\". Do you have the corresponding core installed?",
"openBoardsConfig": "Select other board and port…",
"boardListItem": "{0} at {1}",
"selectBoardForInfo": "Please select a board to obtain board info.",
"platformMissing": "The platform for the selected '{0}' board is not installed.",
"selectPortForInfo": "Please select a port to obtain board info.",
"boardInfo": "Board Info",
"board": "Board{0}",
"port": "Port{0}",
"getBoardInfo": "Get Board Info",
"inSketchbook": " (in Sketchbook)"
},
"boardsManager": "Boards Manager",
"about": {
"label": "About {0}",
"detail": "Version: {0}\nDate: {1}{2}\nCLI Version: {3}{4} [{5}]\n\n{6}"
},
"contributions": {
"addFile": "Add File",
"replaceTitle": "Replace",
"fileAdded": "One file added to the sketch."
},
"replaceMsg": "Replace the existing version of {0}?",
"library": {
"addZip": "Add .ZIP Library...",
"zipLibrary": "Library",
"overwriteExistingLibrary": "Do you want to overwrite the existing library?",
"successfullyInstalledZipLibrary": "Successfully installed library from {0} archive",
"namedLibraryAlreadyExists": "A library folder named {0} already exists. Do you want to overwrite it?",
"libraryAlreadyExists": "A library already exists. Do you want to overwrite it?",
"include": "Include Library",
"manageLibraries": "Manage Libraries...",
"arduinoLibraries": "Arduino libraries",
"contributedLibraries": "Contributed libraries",
"title": "Library Manager",
"needsOneDependency": "The library <b>{0}:{1}</b> needs another dependency currently not installed:",
"needsMultipleDependencies": "The library <b>{0}:{1}</b> needs some other dependencies currently not installed:",
"installOneMissingDependency": "Would you like to install the missing dependency?",
"installMissingDependencies": "Would you like to install all the missing dependencies?",
"dependenciesForLibrary": "Dependencies for library {0}:{1}",
"installAll": "Install all",
"installOnly": "Install {0} only",
"installedSuccessfully": "Successfully installed library {0}:{1}",
"uninstalledSuccessfully": "Successfully uninstalled library {0}:{1}"
},
"selectZip": "Select a zip file containing the library you'd like to add",
"sketch": {
"archiveSketch": "Archive Sketch",
"saveSketchAs": "Save sketch folder as...",
"createdArchive": "Created archive '{0}'.",
"new": "New",
"openRecent": "Open Recent",
"showFolder": "Show Sketch Folder",
"sketch": "Sketch",
"moving": "Moving",
"movingMsg": "The file \"{0}\" needs to be inside a sketch folder named \"{1}\".\nCreate this folder, move the file, and continue?",
"cantOpen": "A folder named \"{0}\" already exists. Can't open sketch.",
"saveFolderAs": "Save sketch folder as...",
"sketchbook": "Sketchbook",
"upload": "Upload",
"uploadUsingProgrammer": "Upload Using Programmer",
"userFieldsNotFoundError": "Can't find user fields for connected board",
"doneUploading": "Done uploading.",
"configureAndUpload": "Configure And Upload",
"verifyOrCompile": "Verify/Compile",
"exportBinary": "Export Compiled Binary",
"verify": "Verify",
"doneCompiling": "Done compiling.",
"couldNotConnectToSerial": "Could not reconnect to serial port. {0}",
"openSketchInNewWindow": "Open Sketch in New Window",
"openFolder": "Open Folder",
"titleLocalSketchbook": "Local Sketchbook",
"titleSketchbook": "Sketchbook",
"close": "Are you sure you want to close the sketch?"
},
"bootloader": {
"burnBootloader": "Burn Bootloader",
"doneBurningBootloader": "Done burning bootloader."
},
"editor": {
"copyForForum": "Copy for Forum (Markdown)",
"commentUncomment": "Comment/Uncomment",
"increaseIndent": "Increase Indent",
"decreaseIndent": "Decrease Indent",
"increaseFontSize": "Increase Font Size",
"decreaseFontSize": "Decrease Font Size",
"autoFormat": "Auto Format"
},
"examples": {
"menu": "Examples",
"couldNotInitializeExamples": "Could not initialize built-in examples.",
"builtInExamples": "Built-in examples",
"customLibrary": "Examples from Custom Libraries",
"for": "Examples for {0}",
"forAny": "Examples for any board"
},
"help": {
"search": "Search on Arduino.cc",
"keyword": "Type a keyword",
"gettingStarted": "Getting Started",
"environment": "Environment",
"troubleshooting": "Troubleshooting",
"reference": "Reference",
"findInReference": "Find in Reference",
"faq": "Frequently Asked Questions",
"visit": "Visit Arduino.cc",
"privacyPolicy": "Privacy Policy"
},
"certificate": {
"uploadRootCertificates": "Upload SSL Root Certificates",
"openContext": "Open context",
"remove": "Remove",
"upload": "Upload",
"addURL": "Add URL to fetch SSL certificate",
"enterURL": "Enter URL",
"selectCertificateToUpload": "1. Select certificate to upload",
"addNew": "Add New",
"selectDestinationBoardToUpload": "2. Select destination board and upload certificate",
"uploadingCertificates": "Uploading certificates.",
"certificatesUploaded": "Certificates uploaded.",
"uploadFailed": "Upload failed. Please try again.",
"selectBoard": "Select a board...",
"boardAtPort": "{0} at {1}",
"noSupportedBoardConnected": "No supported board connected"
},
"firmware": {
"updater": "WiFi101 / WiFiNINA Firmware Updater",
"selectBoard": "Select Board",
"checkUpdates": "Check Updates",
"selectVersion": "Select firmware version",
"install": "Install",
"overwriteSketch": "Installation will overwrite the Sketch on the board.",
"installingFirmware": "Installing firmware.",
"successfullyInstalled": "Firmware successfully installed.",
"failedInstall": "Installation failed. Please try again."
},
"dialog": {
"dontAskAgain": "Don't ask again"
},
"userFields": {
"cancel": "Cancel",
"upload": "Upload"
},
"serial": {
"toggleTimestamp": "Toggle Timestamp",
"autoscroll": "Autoscroll",
"timestamp": "Timestamp",
"noLineEndings": "No Line Ending",
"newLine": "New Line",
"carriageReturn": "Carriage Return",
"newLineCarriageReturn": "Both NL & CR",
"notConnected": "Not connected. Select a board and a port to connect automatically.",
"message": "Message ({0} + Enter to send message to '{1}' on '{2}')",
"connectionBusy": "Connection failed. Serial port is busy: {0}",
"disconnected": "Disconnected {0} from {1}.",
"unexpectedError": "Unexpected error. Reconnecting {0} on port {1}.",
"failedReconnect": "Failed to reconnect {0} to serial port after 10 consecutive attempts. The {1} serial port is busy.",
"reconnect": "Reconnecting {0} to {1} in {2} seconds..."
},
"component": {
"uninstall": "Uninstall",
"uninstallMsg": "Do you want to uninstall {0}?",
"by": "by",
"version": "Version {0}",
"moreInfo": "More info",
"install": "INSTALL",
"filterSearch": "Filter your search..."
},
"electron": {
"couldNotSave": "Could not save the sketch. Please copy your unsaved work into your favorite text editor, and restart the IDE.",
"unsavedChanges": "Any unsaved changes will not be saved."
},
"compile": {
"error": "Compilation error: {0}"
},
"upload": {
"error": "{0} error: {1}"
},
"burnBootloader": {
"error": "Error while burning the bootloader: {0}"
}
},
"theia": {
"core": {
"couldNotSave": "Could not save the sketch. Please copy your unsaved work into your favorite text editor, and restart the IDE.",
"offline": "Offline",
"daemonOffline": "CLI Daemon Offline",
"cannotConnectBackend": "Cannot connect to the backend.",
"cannotConnectDaemon": "Cannot connect to the CLI daemon."
},
"debug": {
"start": "Start...",
"typeNotSupported": "The debug session type \"{0}\" is not supported.",
"startError": "There was an error starting the debug session, check the logs for more details."
},
"editor": {
"unsavedTitle": "Unsaved {0}"
},
"messages": {
"expand": "Expand",
"collapse": "Collapse"
},
"workspace": {
"fileNewName": "Name for new file",
"invalidFilename": "Invalid filename.",
"invalidExtension": ".{0} is not a valid extension",
"newFileName": "New name for file",
"deleteCurrentSketch": "Do you want to delete the current sketch?",
"sketchDirectoryError": "There was an error creating the sketch directory. See the log for more details. The application will probably not work as expected."
}
},
"cloud": {
"GoToCloud": "GO TO CLOUD"
}
}

View File

@@ -6,7 +6,7 @@
"selectedOn": "su {0}", "selectedOn": "su {0}",
"notConnected": "[non connesso]", "notConnected": "[non connesso]",
"serialMonitor": "Monitor seriale", "serialMonitor": "Monitor seriale",
"oldFormat": "The '{0}' still uses the old `.pde` format. Do you want to switch to the new `.ino` extension?", "oldFormat": "Il '{0}' utilizza ancora il vecchio formato `.pde` . Vuoi sostituirlo con la nuova estensione `.ino?",
"later": "Salta", "later": "Salta",
"selectBoard": "Seleziona Scheda", "selectBoard": "Seleziona Scheda",
"unknown": "Sconosciuto", "unknown": "Sconosciuto",
@@ -15,20 +15,20 @@
"loseChanges": "Se non salvi, tutti i cambiamenti saranno persi." "loseChanges": "Se non salvi, tutti i cambiamenti saranno persi."
}, },
"ide-updater": { "ide-updater": {
"errorCheckingForUpdates": "Error while checking for Arduino IDE updates.\n{0}", "errorCheckingForUpdates": "Si è verificato un errore durante il controllo degli aggiornamenti per Arduino IDE {0} .",
"notNowButton": "Not now", "notNowButton": "Non ora",
"versionDownloaded": "Arduino IDE {0} has been downloaded.", "versionDownloaded": "L'Arduino IDE ( 1 {0} ) è stato correttamente scaricato.",
"closeToInstallNotice": "Close the software and install the update on your machine.", "closeToInstallNotice": "Chiudi il software e installa laggiornamento sulla tua macchina",
"closeAndInstallButton": "Chiudi e Installa", "closeAndInstallButton": "Chiudi e Installa",
"downloadingNotice": "Downloading the latest version of the Arduino IDE.", "downloadingNotice": "Stai scaricando lultima versione dellArduino IDE",
"updateAvailable": "Update Available", "updateAvailable": "Aggiornamento disponibile",
"newVersionAvailable": "A new version of Arduino IDE ({0}) is available for download.", "newVersionAvailable": "La nuova versione (1{0}) di Arduino IDE è disponibile per il download.",
"skipVersionButton": "Salta questa versione", "skipVersionButton": "Salta questa versione",
"downloadButton": "Download", "downloadButton": "Scarica",
"goToDownloadPage": "An update for the Arduino IDE is available, but we're not able to download and install it automatically. Please go to the download page and download the latest version from there.", "goToDownloadPage": "E' disponibile un nuovo aggiornamento per Arduino IDE, ma attualmente non è possibile scaricarlo ne tantomeno installarlo in modalità automatica. Si consiglia di andare sul sito ufficiale e dalla pagina download scaricare l'ultima versione disponibile. ",
"goToDownloadButton": "Go To Download", "goToDownloadButton": "Clicca per scaricare",
"ideUpdaterDialog": "Software Update", "ideUpdaterDialog": "Aggiornamento software",
"noUpdatesAvailable": "There are no recent updates available for the Arduino IDE" "noUpdatesAvailable": "Non ci sono aggiornamenti recenti per Arduino IDE "
}, },
"menu": { "menu": {
"sketch": "Sketch", "sketch": "Sketch",
@@ -41,24 +41,24 @@
"debuggingNotSupported": "Il debug non è supportato da '{0}'" "debuggingNotSupported": "Il debug non è supportato da '{0}'"
}, },
"preferences": { "preferences": {
"language.log": "True if the Arduino Language Server should generate log files into the sketch folder. Otherwise, false. It's false by default.", "language.log": "Imposta su True se vuoi che l'Arduino Language Server generi il file di log all'interno della cartella dello sketch. Diversamente, imposta su false. L'impostazione predefinita è false.",
"compile.verbose": "Vero per compilazione esplicita. Falso come opzione predefinita", "compile.verbose": "Vero per compilazione esplicita. Falso come opzione predefinita",
"compile.warnings": "Tells gcc which warning level to use. It's 'None' by default", "compile.warnings": "Indica a gcc il livello di avviso che deve mostrare. Il valore predefinito è 'None' ",
"upload.verbose": "True for verbose upload output. False by default.", "upload.verbose": " Seleziona Vero per un rapporto dettagliato durante l'upload. Il valore predefinito è impostato su falso",
"window.autoScale": "True if the user interface automatically scales with the font size.", "window.autoScale": "Impostato su True l'interfaccia scala automaticamente in base alla dimensione del font .",
"window.zoomLevel": "Regola il livello di zoom della finestra. La dimensione originale è 0 e ogni incremento sopra (es. 1) o sotto (es. -1) rappresenta lo zoom del 20% in più o in meno. Puoi anche inserire i decimali per regolare il livello di zoom con una granularità più fine.", "window.zoomLevel": "Regola il livello di zoom della finestra. La dimensione originale è 0 e ogni incremento sopra (es. 1) o sotto (es. -1) rappresenta lo zoom del 20% in più o in meno. Puoi anche inserire i decimali per regolare il livello di zoom con una granularità più fine.",
"ide.updateChannel": "Release channel to get updated from. 'stable' is the stable release, 'nightly' is the latest development build.", "ide.updateChannel": "Canale di rilascio per le versioni aggiornate. 'stable' è per le versioni stabili, 'nightly' è per l'ultima versione in sviluppo.",
"board.certificates": "Lista dei certificati che possono essere caricati nelle schede", "board.certificates": "Lista dei certificati che possono essere caricati nelle schede",
"sketchbook.showAllFiles": "Vero per mostrare tutti i file relativi contenuti all'interno dello sketch. L'opzione predefinita è falso.", "sketchbook.showAllFiles": "Vero per mostrare tutti i file relativi contenuti all'interno dello sketch. L'opzione predefinita è falso.",
"cloud.enabled": "True if the sketch sync functions are enabled. Defaults to true.", "cloud.enabled": "Imposta su true per abilitare le funzioni di sincronia dello sketch. Il valore predefinito è true.",
"cloud.pull.warn": "True if users should be warned before pulling a cloud sketch. Defaults to true.", "cloud.pull.warn": "Imposta su true se gli utenti devono essere avvisato dopo avere effettuato il pull dello sketch sul cloud. Il valore predefinito è true.",
"cloud.push.warn": "True if users should be warned before pushing a cloud sketch. Defaults to true.", "cloud.push.warn": "Imposta su True se gli utenti devono essere avvisati prima di eseguire l'invio di uno sketch cloud. Il valore predefinito è true.",
"cloud.pushpublic.warn": "True if users should be warned before pushing a public sketch to the cloud. Defaults to true.", "cloud.pushpublic.warn": "True se gli utenti devono essere avvisati prima di eseguire l'invio di uno sketch pubblico nel cloud. Il valore predefinito è true.",
"cloud.sketchSyncEnpoint": "The endpoint used to push and pull sketches from a backend. By default it points to Arduino Cloud API.", "cloud.sketchSyncEnpoint": "La destinazione utilizzata per inviare e richiedere gli schizzi da un back-end. L'impostazione predefinita utilizza Arduino Cloud API.",
"auth.clientID": "il Client ID OAuth2.", "auth.clientID": "il Client ID OAuth2.",
"auth.domain": "Dominio OAuth2.", "auth.domain": "Dominio OAuth2.",
"auth.audience": "The OAuth2 audience.", "auth.audience": "Protocollo pubblico OAuth2",
"auth.registerUri": "The URI used to register a new user.", "auth.registerUri": "L'indirizzo utilizzato per la registrazione di un nuovo utente.",
"network": "Rete", "network": "Rete",
"sketchbook.location": "Percorso della cartella degli sketch", "sketchbook.location": "Percorso della cartella degli sketch",
"browse": "Sfoglia", "browse": "Sfoglia",
@@ -71,146 +71,146 @@
"compile": "compilazione", "compile": "compilazione",
"upload": "caricamento", "upload": "caricamento",
"verifyAfterUpload": "Verifica il codice dopo il caricamento", "verifyAfterUpload": "Verifica il codice dopo il caricamento",
"editorQuickSuggestions": "Editor Quick Suggestions", "editorQuickSuggestions": "Suggerimenti rapidi dell'editor",
"additionalManagerURLs": "URL aggiuntive per il Gestore schede", "additionalManagerURLs": "URL aggiuntive per il Gestore schede",
"noProxy": "Nessun proxy", "noProxy": "Nessun proxy",
"manualProxy": "Configurazione manuale del proxy", "manualProxy": "Configurazione manuale del proxy",
"newSketchbookLocation": "Seleziona un percorso per il nuovo sketchbook", "newSketchbookLocation": "Seleziona un percorso per il nuovo sketchbook",
"choose": "Scegli", "choose": "Scegli",
"enterAdditionalURLs": "Enter additional URLs, one for each row", "enterAdditionalURLs": "Aggiungi degli URLs aggiuntivi, uno per ogni riga",
"unofficialBoardSupport": "Click for a list of unofficial board support URLs", "unofficialBoardSupport": "Clicca per ottenere la lista di collegamenti per le schede di terze parti, non schede ufficiali.",
"invalid.sketchbook.location": "Invalid sketchbook location: {0}", "invalid.sketchbook.location": "Posizione dello sketchbook non valida: {0}",
"invalid.editorFontSize": "Invalid editor font size. It must be a positive integer.", "invalid.editorFontSize": "Dimensione del carattere dell'editor non valida. Deve essere un numero intero positivo.",
"invalid.theme": "Tema non valido" "invalid.theme": "Tema non valido"
}, },
"cloud": { "cloud": {
"signIn": "SIGN IN", "signIn": "COLLEGATI",
"signOut": "Sign Out", "signOut": "Disconnetti",
"chooseSketchVisibility": "Choose visibility of your Sketch:", "chooseSketchVisibility": "Scegli a chi far vedere il tuo Sketch:",
"privateVisibility": "Privato. Solo tu potrai vedere lo sketch.", "privateVisibility": "Privato. Solo tu potrai vedere lo sketch.",
"publicVisibility": "Public. Anyone with the link can view the Sketch.", "publicVisibility": "Pubblico. Chiunque abbia il link può vedere lo Sketch.",
"link": "Link:", "link": "Link:",
"embed": "Embed:", "embed": "Includi:",
"cloudSketchbook": "Cloud Sketchbook", "cloudSketchbook": "Cloud Sketchbook",
"shareSketch": "Condividi sketch", "shareSketch": "Condividi sketch",
"showHideRemoveSketchbook": "Show/Hide Remote Sketchbook", "showHideRemoveSketchbook": "Mostra/Nascondi la raccolta Remota degli Schetch",
"pullSketch": "Pull Sketch", "pullSketch": "Richiedi lo Sketch",
"openInCloudEditor": "Open in Cloud Editor", "openInCloudEditor": "Apri nell'editor del Cloud",
"options": "Opzioni...", "options": "Opzioni...",
"share": "Condividi...", "share": "Condividi...",
"remote": "Remoto", "remote": "Remoto",
"emptySketchbook": "Lo Sketchbook è vuoto", "emptySketchbook": "Lo Sketchbook è vuoto",
"visitArduinoCloud": "Visita Arduino Cloud per creare Cloud Sketch ", "visitArduinoCloud": "Visita Arduino Cloud per creare Cloud Sketch ",
"signInToCloud": "Sign in to Arduino Cloud", "signInToCloud": "Effettua la registrazione su Arduino Cloud",
"syncEditSketches": "Sync and edit your Arduino Cloud Sketches", "syncEditSketches": "Sincronizza e modifica la tua raccolta di Sketches sul Cloud Arduino",
"learnMore": "Più informazioni", "learnMore": "Più informazioni",
"continue": "Continua", "continue": "Continua",
"pushSketch": "Push Sketch", "pushSketch": "Invia lo Sketch",
"pushSketchMsg": "This is a Public Sketch. Before pushing, make sure any sensitive information is defined in arduino_secrets.h files. You can make a Sketch private from the Share panel.", "pushSketchMsg": "Questo è uno sketch pubblico. Prima di inviarlo, verifica che tutte le informazioni sensibili siano all'interno di arduino_secrets.h. Eventualmente puoi rendere lo sketch privato dal Pannello di Condivisione.",
"pull": "Pull", "pull": "Richiedi",
"pullSketchMsg": "Pulling this Sketch from the Cloud will overwrite its local version. Are you sure you want to continue?", "pullSketchMsg": "Richiedendo questo Sketch tramite il Cloud, lo stesso sovrascriverà quello presente in locale. Sei sicuro di dover continuare?",
"donePulling": "Done pulling {0}.", "donePulling": "Pulling terminato {0}.",
"notYetPulled": "Cannot push to Cloud. It is not yet pulled.", "notYetPulled": "Sul Cloud non puoi effettuare il push se non hai ancora fatto il pull",
"push": "Push", "push": "Push",
"pullFirst": "You have to pull first to be able to push to the Cloud.", "pullFirst": "Nel Cloud devi prima effettuare il Pull per poi poter eseguire il Push.",
"donePushing": "Done pushing {0}.", "donePushing": "Invio terminato {0}.",
"connected": "Connesso", "connected": "Connesso",
"offline": "Fuori linea", "offline": "Fuori linea",
"profilePicture": "Profile picture" "profilePicture": "Immagine profilo"
}, },
"board": { "board": {
"installManually": "Installa manualmente", "installManually": "Installa manualmente",
"installNow": "The \"{0} {1}\" core has to be installed for the currently selected \"{2}\" board. Do you want to install it now?", "installNow": "Il \"{0} {1}\" core non è installato per la scheda \"{2}\" . Vuoi installarlo ora?",
"configDialogTitle": "Seleziona un'altra scheda o porta", "configDialogTitle": "Seleziona un'altra scheda o porta",
"configDialog1": "Seleziona una scheda ed una porta se vuoi inviare lo sketch.", "configDialog1": "Seleziona una scheda ed una porta se vuoi inviare lo sketch.",
"configDialog2": "If you only select a Board you will be able to compile, but not to upload your sketch.", "configDialog2": "Se selezioni solo una Board potrai compilare, ma non caricare il tuo sketch.",
"pleasePickBoard": "Please pick a board connected to the port you have selected.", "pleasePickBoard": "Scegli la scheda collegata alla porta che hai selezionato.",
"showAllAvailablePorts": "Shows all available ports when enabled", "showAllAvailablePorts": "Quando abilitato, mostra tutte le porte disponibili",
"programmer": "Programmatore", "programmer": "Programmatore",
"succesfullyInstalledPlatform": "Successfully installed platform {0}:{1}", "succesfullyInstalledPlatform": "Piattaforma installata correttamente {0}:{1}",
"succesfullyUninstalledPlatform": "Successfully uninstalled platform {0}:{1}", "succesfullyUninstalledPlatform": "Piattaforma disinstallata correttamente {0}:{1}",
"couldNotFindPreviouslySelected": "Could not find previously selected board '{0}' in installed platform '{1}'. Please manually reselect the board you want to use. Do you want to reselect it now?", "couldNotFindPreviouslySelected": "Impossibile trovare la scehda selezionata '{0}' nelle piattaforme installate '{1}'. Scegli nuovamente la scheda che vuoi utilizzare. Vuoi sceglierla ora?",
"reselectLater": "Reselect later", "reselectLater": "Riselezionare più tardi",
"noneSelected": "Nessuna scheda selezionata.", "noneSelected": "Nessuna scheda selezionata.",
"noPortsSelected": "No ports selected for board: '{0}'.", "noPortsSelected": "Nessuna porta selezionata per la scheda: '{0}'.",
"noFQBN": "The FQBN is not available for the selected board \"{0}\". Do you have the corresponding core installed?", "noFQBN": "La FQBN non è disponibile per la scheda selezionata\"{0}\". Sei sicuro che il core specifico sia stato installato?",
"openBoardsConfig": "Select other board and port", "openBoardsConfig": "Scegli un'altra scheda e un altra porta...",
"boardListItem": "{0} a {1}", "boardListItem": "{0} a {1}",
"selectBoardForInfo": "Please select a board to obtain board info.", "selectBoardForInfo": "Seleziona la scheda per la quale desideri informazioni.",
"platformMissing": "The platform for the selected '{0}' board is not installed.", "platformMissing": "La piattaforma per la scheda '{0}' non è installata.",
"selectPortForInfo": "Please select a port to obtain board info.", "selectPortForInfo": "Selezionare la porta per ottenere info sulla scheda.",
"boardInfo": "Informazioni sulla scheda", "boardInfo": "Informazioni sulla scheda",
"board": "Scheda{0}", "board": "Scheda{0}",
"port": "Porta{0}", "port": "Porta{0}",
"getBoardInfo": "Get Board Info", "getBoardInfo": "Acquisisci informazioni sulla Scheda",
"inSketchbook": " (in Sketchbook)" "inSketchbook": " (nella raccolta sketch)"
}, },
"boardsManager": "Gestore schede", "boardsManager": "Gestore schede",
"about": { "about": {
"label": "About {0}", "label": "Informazioni su {0}",
"detail": "Version: {0}\nDate: {1}{2}\nCLI Version: {3}{4} [{5}]\n\n{6}" "detail": "Versione: {0}\nData: {1}{2}\nVersione CLI : {3}{4} [{5}]\n{6}"
}, },
"contributions": { "contributions": {
"addFile": "Aggiungi file...", "addFile": "Aggiungi file...",
"replaceTitle": "Sostituisci", "replaceTitle": "Sostituisci",
"fileAdded": "One file added to the sketch." "fileAdded": "Aggiunto un file allo sketch."
}, },
"replaceMsg": "Replace the existing version of {0}?", "replaceMsg": "Sostituisce la versione esistente con la versione 1{0} ?",
"library": { "library": {
"addZip": "Aggiungi libreria da file .ZIP...", "addZip": "Aggiungi libreria da file .ZIP...",
"zipLibrary": "Libreria", "zipLibrary": "Libreria",
"overwriteExistingLibrary": "Do you want to overwrite the existing library?", "overwriteExistingLibrary": "Vuoi sovrascrivere la libreria esistente?",
"successfullyInstalledZipLibrary": "La libreria è stata installata con successo dalla cartella {0}", "successfullyInstalledZipLibrary": "La libreria è stata installata con successo dalla cartella {0}",
"namedLibraryAlreadyExists": "A library folder named {0} already exists. Do you want to overwrite it?", "namedLibraryAlreadyExists": "La cartella con nome {0} esiste già. Vuoi sovrascriverla?",
"libraryAlreadyExists": "A library already exists. Do you want to overwrite it?", "libraryAlreadyExists": "Libreria già presente. Vuoi sovrascriverla?",
"include": "Includi Libreria", "include": "Includi Libreria",
"manageLibraries": "Gestisci Librerie", "manageLibraries": "Gestisci Librerie",
"arduinoLibraries": "Librerie Arduino", "arduinoLibraries": "Librerie Arduino",
"contributedLibraries": "Contributed libraries", "contributedLibraries": "Librerie di terze parti",
"title": "Gestore Librerie", "title": "Gestore Librerie",
"needsOneDependency": "The library <b>{0}:{1}</b> needs another dependency currently not installed:", "needsOneDependency": "La libreria <b>{0}:{1}</b> necessità di dipendenze che attualmente non sono installate:",
"needsMultipleDependencies": "The library <b>{0}:{1}</b> needs some other dependencies currently not installed:", "needsMultipleDependencies": "La libreria <b>{0}:{1}</b> di altre dipendenze che al momento non risultano installate:",
"installOneMissingDependency": "Would you like to install the missing dependency?", "installOneMissingDependency": "Vorresti installare le dipendenze mancanti?",
"installMissingDependencies": "Would you like to install all the missing dependencies?", "installMissingDependencies": "Vorresti installare tutte le dipendenze mancanti?",
"dependenciesForLibrary": "Dependencies for library {0}:{1}", "dependenciesForLibrary": "Dipendenze per la libreria {0}:{1}",
"installAll": "Installa tutto", "installAll": "Installa tutto",
"installOnly": "Installa {0} solamente", "installOnly": "Installa {0} solamente",
"installedSuccessfully": "Successfully installed library {0}:{1}", "installedSuccessfully": "Libreria installata correttamente 1{0} : 2{1} ",
"uninstalledSuccessfully": "Successfully uninstalled library {0}:{1}" "uninstalledSuccessfully": "Libreria disinstallata con successo 1{0} : 2{1}"
}, },
"selectZip": "Select a zip file containing the library you'd like to add", "selectZip": "Scegli il file zip che contiene la libreria che vuoi aggiungere",
"sketch": { "sketch": {
"archiveSketch": "Archivia sketch", "archiveSketch": "Archivia sketch",
"saveSketchAs": "Salva la cartella dello sketch come...", "saveSketchAs": "Salva la cartella dello sketch come...",
"createdArchive": "Created archive '{0}'.", "createdArchive": "Creato l'archivio '{0}'.",
"new": "Nuovo", "new": "Nuovo",
"openRecent": "Apri recenti", "openRecent": "Apri recenti",
"showFolder": "Mostra la cartella dello Sketch", "showFolder": "Mostra la cartella dello Sketch",
"sketch": "Sketch", "sketch": "Sketch",
"moving": "Spostando", "moving": "Spostando",
"movingMsg": "The file \"{0}\" needs to be inside a sketch folder named \"{1}\".\nCreate this folder, move the file, and continue?", "movingMsg": "Il file \"{0}\" deve essere all'interno della cartella \"{1}\".\nCreare questa cartella, spostare il file e continuare?",
"cantOpen": "Una cartella di nome \"{0}\" esiste già. Impossibile aprire lo sketch.", "cantOpen": "Una cartella di nome \"{0}\" esiste già. Impossibile aprire lo sketch.",
"saveFolderAs": "Save sketch folder as...", "saveFolderAs": "Salva la cartella sketch come...",
"sketchbook": "Sketchbook", "sketchbook": "Raccolta degli sketch",
"upload": "Upload", "upload": "Caricare",
"uploadUsingProgrammer": "Upload Using Programmer", "uploadUsingProgrammer": "Carica tramite Programmatore",
"userFieldsNotFoundError": "Can't find user fields for connected board", "userFieldsNotFoundError": "Non è possibile trovare i campi utente per connettere la scheda",
"doneUploading": "Done uploading.", "doneUploading": "Caricamento terminato.",
"configureAndUpload": "Configure And Upload", "configureAndUpload": "Configurare e caricare",
"verifyOrCompile": "Verifica/Compila", "verifyOrCompile": "Verifica/Compila",
"exportBinary": "Esporta sketch compilato", "exportBinary": "Esporta sketch compilato",
"verify": "Verifica", "verify": "Verifica",
"doneCompiling": "Compilazione completata.", "doneCompiling": "Compilazione completata.",
"couldNotConnectToSerial": "Could not reconnect to serial port. {0}", "couldNotConnectToSerial": "Non è possibile riconnettersi alla porta seriale. 1{0}",
"openSketchInNewWindow": "Open Sketch in New Window", "openSketchInNewWindow": "Apri lo sketch in una Nuova Finestra.",
"openFolder": "Apri Cartella", "openFolder": "Apri Cartella",
"titleLocalSketchbook": "Local Sketchbook", "titleLocalSketchbook": "Cartella degli sketch locali",
"titleSketchbook": "Sketchbook", "titleSketchbook": "Sketchbook",
"close": "Sei sicuro di voler chiudere lo sketch?" "close": "Sei sicuro di voler chiudere lo sketch?"
}, },
"bootloader": { "bootloader": {
"burnBootloader": "Scrivi il bootloader", "burnBootloader": "Scrivi il bootloader",
"doneBurningBootloader": "Done burning bootloader." "doneBurningBootloader": "La scritture de bootloader è terminata."
}, },
"editor": { "editor": {
"copyForForum": "Copia per il forum (Markdown)", "copyForForum": "Copia per il forum (Markdown)",
@@ -223,50 +223,50 @@
}, },
"examples": { "examples": {
"menu": "Esempi", "menu": "Esempi",
"couldNotInitializeExamples": "Could not initialize built-in examples.", "couldNotInitializeExamples": "Impossibile inizializzare gli esempi incorporati.",
"builtInExamples": "Esempi integrati", "builtInExamples": "Esempi integrati",
"customLibrary": "Examples from Custom Libraries", "customLibrary": "Esempi da librerie di terzi",
"for": "Esempi per {0}", "for": "Esempi per {0}",
"forAny": "Esempi per tutte le schede" "forAny": "Esempi per tutte le schede"
}, },
"help": { "help": {
"search": "Cerca su Arduino.cc", "search": "Cerca su Arduino.cc",
"keyword": "Digita una parola chiave", "keyword": "Digita una parola chiave",
"gettingStarted": "Getting Started", "gettingStarted": "Guida introduttiva",
"environment": "Environment", "environment": "Ambiente di sviluppo",
"troubleshooting": "Troubleshooting", "troubleshooting": "Risoluzione dei problemi",
"reference": "Riferimenti", "reference": "Riferimenti",
"findInReference": "Find in Reference", "findInReference": "Trova riferimento alla selezione",
"faq": "Frequently Asked Questions", "faq": "Domande poste frequentemente",
"visit": "Visit Arduino.cc", "visit": "Vai al sito Arduino.cc",
"privacyPolicy": "Privacy Policy" "privacyPolicy": "Politica sulla riservatezza"
}, },
"certificate": { "certificate": {
"uploadRootCertificates": "Upload SSL Root Certificates", "uploadRootCertificates": "Carica i tuoi certificati SSL Root",
"openContext": "Open context", "openContext": "Apri una contestazione",
"remove": "Rimuovi", "remove": "Rimuovi",
"upload": "Carica", "upload": "Carica",
"addURL": "Add URL to fetch SSL certificate", "addURL": "Aggiungi un URL per acquisire il certificato SSL",
"enterURL": "Inserisci URL", "enterURL": "Inserisci URL",
"selectCertificateToUpload": "1. Select certificate to upload", "selectCertificateToUpload": "1. Scegli il certificato da caricare",
"addNew": "Aggiungi nuovo", "addNew": "Aggiungi nuovo",
"selectDestinationBoardToUpload": "2. Select destination board and upload certificate", "selectDestinationBoardToUpload": "2. Scegli la scheda e carica i certificati",
"uploadingCertificates": "Uploading certificates.", "uploadingCertificates": "Caricamento dei certificati.",
"certificatesUploaded": "Certificates uploaded.", "certificatesUploaded": "Certificati caricati.",
"uploadFailed": "Upload failed. Please try again.", "uploadFailed": "Caricamento fallito. Si prega di riprovare.",
"selectBoard": "Seleziona una scheda...", "selectBoard": "Seleziona una scheda...",
"boardAtPort": "{0} a {1}", "boardAtPort": "{0} a {1}",
"noSupportedBoardConnected": "No supported board connected" "noSupportedBoardConnected": "La scheda collegata non è supportata."
}, },
"firmware": { "firmware": {
"updater": "WiFi101 / WiFiNINA Firmware Updater", "updater": "WiFi101 / WiFiNINA Aggiornamento Frmware",
"selectBoard": "Seleziona la scheda", "selectBoard": "Seleziona la scheda",
"checkUpdates": "Verifica aggiornamenti", "checkUpdates": "Verifica aggiornamenti",
"selectVersion": "Selezione la versione del firmware", "selectVersion": "Selezione la versione del firmware",
"install": "Installa", "install": "Installa",
"overwriteSketch": "Installation will overwrite the Sketch on the board.", "overwriteSketch": "L'installazione sovrascriverà lo sketch presente nella scheda.",
"installingFirmware": "Installazione del firmware", "installingFirmware": "Installazione del firmware",
"successfullyInstalled": "Firmware successfully installed.", "successfullyInstalled": "Firmware correttamente installato.",
"failedInstall": "Installazione fallita. Riprova" "failedInstall": "Installazione fallita. Riprova"
}, },
"dialog": { "dialog": {
@@ -277,39 +277,39 @@
"upload": "Carica" "upload": "Carica"
}, },
"serial": { "serial": {
"toggleTimestamp": "Toggle Timestamp", "toggleTimestamp": "Alterna il Timestamp",
"autoscroll": "Scorrimento automatico", "autoscroll": "Scorrimento automatico",
"timestamp": "Timestamp", "timestamp": "Marca temporale",
"noLineEndings": "Nessun fine riga", "noLineEndings": "Nessun fine riga",
"newLine": "A capo (NL)", "newLine": "A capo (NL)",
"carriageReturn": "Ritorno carrello (CR)", "carriageReturn": "Ritorno carrello (CR)",
"newLineCarriageReturn": "Entrambi NL & CR", "newLineCarriageReturn": "Entrambi NL & CR",
"notConnected": "Not connected. Select a board and a port to connect automatically.", "notConnected": "Non collegato. Scegli una scheda e la porta di comunicazione per una connessione automatica.",
"message": "Message ({0} + Enter to send message to '{1}' on '{2}')", "message": "Messaggio({0} + Invio per inviare il messaggio a '{1}' su '{2}')",
"connectionBusy": "Connection failed. Serial port is busy: {0}", "connectionBusy": "Connessione fallita. La porta seriale è occupata: 1{0}",
"disconnected": "Disconnected {0} from {1}.", "disconnected": "Disconnesso 1{0} da 2{1} .",
"unexpectedError": "Unexpected error. Reconnecting {0} on port {1}.", "unexpectedError": "Errore imprevisto. Riconnessione 1{0} nella porta 2{1} .",
"failedReconnect": "Failed to reconnect {0} to serial port after 10 consecutive attempts. The {1} serial port is busy.", "failedReconnect": "Connessione alla porta seriale 1 {0} fallita dopo 10 tentativi. La 2{1} porta seriale è occupata.",
"reconnect": "Reconnecting {0} to {1} in {2} seconds..." "reconnect": "Riconnessione da 1 {0} a 2 {1} tra {2} secondi..."
}, },
"component": { "component": {
"uninstall": "Disinstalla", "uninstall": "Disinstalla",
"uninstallMsg": "Do you want to uninstall {0}?", "uninstallMsg": "Vuoi veramente disinstallare 1 {0} ?",
"by": "by", "by": "da",
"version": "Versione {0}", "version": "Versione {0}",
"moreInfo": "Maggiori informazioni", "moreInfo": "Maggiori informazioni",
"install": "Installa", "install": "Installa",
"filterSearch": "Filtra la tua ricerca..." "filterSearch": "Filtra la tua ricerca..."
}, },
"electron": { "electron": {
"couldNotSave": "Could not save the sketch. Please copy your unsaved work into your favorite text editor, and restart the IDE.", "couldNotSave": "Non è stato possibile salvare lo sketch. Si consiglia di copiarlo è salvarlo su un file di testo e solo successivamente riavviare l' Arduino IDE. ",
"unsavedChanges": "Any unsaved changes will not be saved." "unsavedChanges": "Eventuali modifiche non salvate verranno perse"
}, },
"compile": { "compile": {
"error": "Errore di compilazione: {0}" "error": "Errore di compilazione: {0}"
}, },
"upload": { "upload": {
"error": "{0} error: {1}" "error": "1 {0} errore: 2 {1}"
}, },
"burnBootloader": { "burnBootloader": {
"error": "Errore durante la scrittura del bootloader: {0}" "error": "Errore durante la scrittura del bootloader: {0}"
@@ -317,19 +317,19 @@
}, },
"theia": { "theia": {
"core": { "core": {
"couldNotSave": "Could not save the sketch. Please copy your unsaved work into your favorite text editor, and restart the IDE.", "couldNotSave": "Non è stato possibile salvare lo sketch. Si consiglia di copiarlo è salvarlo su un file di testo e solo successivamente riavviare l' Arduino IDE. ",
"offline": "Offline", "offline": "Disconnesso",
"daemonOffline": "CLI Daemon Offline", "daemonOffline": "Il CLI Daemon è disconnesso",
"cannotConnectBackend": "Non reisco a collegarmi al backend", "cannotConnectBackend": "Non reisco a collegarmi al backend",
"cannotConnectDaemon": "Non riesco a collegarmi al demone CLI" "cannotConnectDaemon": "Non riesco a collegarmi al demone CLI"
}, },
"debug": { "debug": {
"start": "Inizio...", "start": "Inizio...",
"typeNotSupported": "The debug session type \"{0}\" is not supported.", "typeNotSupported": "Il tipo di sessione di debug \" 1 {0} \" non è supportato. ",
"startError": "There was an error starting the debug session, check the logs for more details." "startError": "Si è verificato un problema all'avvio del debug, per ulteriori controlla i logs"
}, },
"editor": { "editor": {
"unsavedTitle": "Unsaved {0}" "unsavedTitle": "Non salvato 1{0}"
}, },
"messages": { "messages": {
"expand": "Espandi", "expand": "Espandi",
@@ -340,8 +340,8 @@
"invalidFilename": "Nome del file invalido", "invalidFilename": "Nome del file invalido",
"invalidExtension": "\".{0}\" non è un'estensione valida", "invalidExtension": "\".{0}\" non è un'estensione valida",
"newFileName": "Nuovo nome del file", "newFileName": "Nuovo nome del file",
"deleteCurrentSketch": "Do you want to delete the current sketch?", "deleteCurrentSketch": "Vuoi eliminare lo sketch attuale?",
"sketchDirectoryError": "There was an error creating the sketch directory. See the log for more details. The application will probably not work as expected." "sketchDirectoryError": "Si è verificato un errore durante la creazione della directory degli sketch. Per ulteriori dettagli guarda il file di log. Probabilmente l'applicazione non funzionerà come previsto."
} }
}, },
"cloud": { "cloud": {

View File

@@ -47,7 +47,7 @@
"upload.verbose": "Verdadeiro para saída de upload detalhada. Falsa é padrão.", "upload.verbose": "Verdadeiro para saída de upload detalhada. Falsa é padrão.",
"window.autoScale": "Verdadeiro se a interface do usuário for dimensionada automaticamente com o tamanho da fonte.", "window.autoScale": "Verdadeiro se a interface do usuário for dimensionada automaticamente com o tamanho da fonte.",
"window.zoomLevel": "Ajuste o nível de zoom da janela. O tamanho original é 0 e cada incremento acima (por exemplo, 1) ou abaixo (por exemplo, -1) representa um zoom 20% maior ou menor. Você também pode inserir decimais para ajustar o nível de zoom para uma maior precisão.", "window.zoomLevel": "Ajuste o nível de zoom da janela. O tamanho original é 0 e cada incremento acima (por exemplo, 1) ou abaixo (por exemplo, -1) representa um zoom 20% maior ou menor. Você também pode inserir decimais para ajustar o nível de zoom para uma maior precisão.",
"ide.updateChannel": "Release channel to get updated from. 'stable' is the stable release, 'nightly' is the latest development build.", "ide.updateChannel": "Canal de lançamento para se atualizar. 'stable' é o lançamento estável, 'nightly' é o último build de desenvolvimento.",
"board.certificates": "Lista de certificados que podem ser carregados nas placas", "board.certificates": "Lista de certificados que podem ser carregados nas placas",
"sketchbook.showAllFiles": "Verdadeiro para mostrar todos os arquivos de sketch dentro do sketch. Falso é padrão.", "sketchbook.showAllFiles": "Verdadeiro para mostrar todos os arquivos de sketch dentro do sketch. Falso é padrão.",
"cloud.enabled": "Verdadeiro se as funções de sincronização de sketch estiverem ativadas. O padrão é verdadeiro.", "cloud.enabled": "Verdadeiro se as funções de sincronização de sketch estiverem ativadas. O padrão é verdadeiro.",
@@ -123,7 +123,7 @@
"installNow": "O núcleo \"{0} {1}\" deve ser instalado para a placa \"{2}\" atualmente selecionada. Quer instalar agora?", "installNow": "O núcleo \"{0} {1}\" deve ser instalado para a placa \"{2}\" atualmente selecionada. Quer instalar agora?",
"configDialogTitle": "Selecionar Outra Placa e Porta", "configDialogTitle": "Selecionar Outra Placa e Porta",
"configDialog1": "Selecione uma placa e uma porta se quiser fazer o upload de um sketch.", "configDialog1": "Selecione uma placa e uma porta se quiser fazer o upload de um sketch.",
"configDialog2": "If you only select a Board you will be able to compile, but not to upload your sketch.", "configDialog2": "Se você somente selecionar uma Placa você será capaz de compilar, mas não de enviar o seu rascunho.",
"pleasePickBoard": "Escolha uma placa conectada à porta que você selecionou.", "pleasePickBoard": "Escolha uma placa conectada à porta que você selecionou.",
"showAllAvailablePorts": "Mostrar todas as portas disponíveis quando habilitado", "showAllAvailablePorts": "Mostrar todas as portas disponíveis quando habilitado",
"programmer": "Programador/Gravador", "programmer": "Programador/Gravador",
@@ -259,7 +259,7 @@
"noSupportedBoardConnected": "Nenhuma placa compatível conectada" "noSupportedBoardConnected": "Nenhuma placa compatível conectada"
}, },
"firmware": { "firmware": {
"updater": "WiFi101 / WiFiNINA Firmware Updater", "updater": "Atualizador de Firmware WiFi101 / WiFiNINA",
"selectBoard": "Selecionar Placa", "selectBoard": "Selecionar Placa",
"checkUpdates": "Verificar Atualizações", "checkUpdates": "Verificar Atualizações",
"selectVersion": "Selecione a versão do firmware", "selectVersion": "Selecione a versão do firmware",

350
i18n/sq.json Normal file
View File

@@ -0,0 +1,350 @@
{
"arduino": {
"common": {
"offlineIndicator": "You appear to be offline. Without an Internet connection, the Arduino CLI might not be able to download the required resources and could cause malfunction. Please connect to the Internet and restart the application.",
"noBoardSelected": "No board selected",
"selectedOn": "on {0}",
"notConnected": "[not connected]",
"serialMonitor": "Serial Monitor",
"oldFormat": "The '{0}' still uses the old `.pde` format. Do you want to switch to the new `.ino` extension?",
"later": "Later",
"selectBoard": "Select Board",
"unknown": "Unknown",
"processing": "Processing",
"saveChangesToSketch": "Do you want to save changes to this sketch before closing?",
"loseChanges": "If you don't save, your changes will be lost."
},
"ide-updater": {
"errorCheckingForUpdates": "Error while checking for Arduino IDE updates.\n{0}",
"notNowButton": "Not now",
"versionDownloaded": "Arduino IDE {0} has been downloaded.",
"closeToInstallNotice": "Close the software and install the update on your machine.",
"closeAndInstallButton": "Close and Install",
"downloadingNotice": "Downloading the latest version of the Arduino IDE.",
"updateAvailable": "Update Available",
"newVersionAvailable": "A new version of Arduino IDE ({0}) is available for download.",
"skipVersionButton": "Skip Version",
"downloadButton": "Download",
"goToDownloadPage": "An update for the Arduino IDE is available, but we're not able to download and install it automatically. Please go to the download page and download the latest version from there.",
"goToDownloadButton": "Go To Download",
"ideUpdaterDialog": "Software Update",
"noUpdatesAvailable": "There are no recent updates available for the Arduino IDE"
},
"menu": {
"sketch": "Sketch",
"tools": "Tools"
},
"debug": {
"optimizeForDebugging": "Optimize for Debugging",
"debugWithMessage": "Debug - {0}",
"noPlatformInstalledFor": "Platform is not installed for '{0}'",
"debuggingNotSupported": "Debugging is not supported by '{0}'"
},
"preferences": {
"language.log": "True if the Arduino Language Server should generate log files into the sketch folder. Otherwise, false. It's false by default.",
"compile.verbose": "True for verbose compile output. False by default",
"compile.warnings": "Tells gcc which warning level to use. It's 'None' by default",
"upload.verbose": "True for verbose upload output. False by default.",
"window.autoScale": "True if the user interface automatically scales with the font size.",
"window.zoomLevel": "Adjust the zoom level of the window. The original size is 0 and each increment above (e.g. 1) or below (e.g. -1) represents zooming 20% larger or smaller. You can also enter decimals to adjust the zoom level with a finer granularity.",
"ide.updateChannel": "Release channel to get updated from. 'stable' is the stable release, 'nightly' is the latest development build.",
"board.certificates": "List of certificates that can be uploaded to boards",
"sketchbook.showAllFiles": "True to show all sketch files inside the sketch. It is false by default.",
"cloud.enabled": "True if the sketch sync functions are enabled. Defaults to true.",
"cloud.pull.warn": "True if users should be warned before pulling a cloud sketch. Defaults to true.",
"cloud.push.warn": "True if users should be warned before pushing a cloud sketch. Defaults to true.",
"cloud.pushpublic.warn": "True if users should be warned before pushing a public sketch to the cloud. Defaults to true.",
"cloud.sketchSyncEnpoint": "The endpoint used to push and pull sketches from a backend. By default it points to Arduino Cloud API.",
"auth.clientID": "The OAuth2 client ID.",
"auth.domain": "The OAuth2 domain.",
"auth.audience": "The OAuth2 audience.",
"auth.registerUri": "The URI used to register a new user.",
"network": "Network",
"sketchbook.location": "Sketchbook location",
"browse": "Browse",
"files.inside.sketches": "Show files inside Sketches",
"editorFontSize": "Editor font size",
"interfaceScale": "Interface scale",
"showVerbose": "Show verbose output during",
"compilerWarnings": "Compiler warnings",
"automatic": "Automatic",
"compile": "compile",
"upload": "upload",
"verifyAfterUpload": "Verify code after upload",
"editorQuickSuggestions": "Editor Quick Suggestions",
"additionalManagerURLs": "Additional Boards Manager URLs",
"noProxy": "No proxy",
"manualProxy": "Manual proxy configuration",
"newSketchbookLocation": "Select new sketchbook location",
"choose": "Choose",
"enterAdditionalURLs": "Enter additional URLs, one for each row",
"unofficialBoardSupport": "Click for a list of unofficial board support URLs",
"invalid.sketchbook.location": "Invalid sketchbook location: {0}",
"invalid.editorFontSize": "Invalid editor font size. It must be a positive integer.",
"invalid.theme": "Invalid theme."
},
"cloud": {
"signIn": "SIGN IN",
"signOut": "Sign Out",
"chooseSketchVisibility": "Choose visibility of your Sketch:",
"privateVisibility": "Private. Only you can view the Sketch.",
"publicVisibility": "Public. Anyone with the link can view the Sketch.",
"link": "Link:",
"embed": "Embed:",
"cloudSketchbook": "Cloud Sketchbook",
"shareSketch": "Share Sketch",
"showHideRemoveSketchbook": "Show/Hide Remote Sketchbook",
"pullSketch": "Pull Sketch",
"openInCloudEditor": "Open in Cloud Editor",
"options": "Options...",
"share": "Share...",
"remote": "Remote",
"emptySketchbook": "Your Sketchbook is empty",
"visitArduinoCloud": "Visit Arduino Cloud to create Cloud Sketches.",
"signInToCloud": "Sign in to Arduino Cloud",
"syncEditSketches": "Sync and edit your Arduino Cloud Sketches",
"learnMore": "Learn more",
"continue": "Continue",
"pushSketch": "Push Sketch",
"pushSketchMsg": "This is a Public Sketch. Before pushing, make sure any sensitive information is defined in arduino_secrets.h files. You can make a Sketch private from the Share panel.",
"pull": "Pull",
"pullSketchMsg": "Pulling this Sketch from the Cloud will overwrite its local version. Are you sure you want to continue?",
"donePulling": "Done pulling {0}.",
"notYetPulled": "Cannot push to Cloud. It is not yet pulled.",
"push": "Push",
"pullFirst": "You have to pull first to be able to push to the Cloud.",
"donePushing": "Done pushing {0}.",
"connected": "Connected",
"offline": "Offline",
"profilePicture": "Profile picture"
},
"board": {
"installManually": "Install Manually",
"installNow": "The \"{0} {1}\" core has to be installed for the currently selected \"{2}\" board. Do you want to install it now?",
"configDialogTitle": "Select Other Board & Port",
"configDialog1": "Select both a Board and a Port if you want to upload a sketch.",
"configDialog2": "If you only select a Board you will be able to compile, but not to upload your sketch.",
"pleasePickBoard": "Please pick a board connected to the port you have selected.",
"showAllAvailablePorts": "Shows all available ports when enabled",
"programmer": "Programmer",
"succesfullyInstalledPlatform": "Successfully installed platform {0}:{1}",
"succesfullyUninstalledPlatform": "Successfully uninstalled platform {0}:{1}",
"couldNotFindPreviouslySelected": "Could not find previously selected board '{0}' in installed platform '{1}'. Please manually reselect the board you want to use. Do you want to reselect it now?",
"reselectLater": "Reselect later",
"noneSelected": "No boards selected.",
"noPortsSelected": "No ports selected for board: '{0}'.",
"noFQBN": "The FQBN is not available for the selected board \"{0}\". Do you have the corresponding core installed?",
"openBoardsConfig": "Select other board and port…",
"boardListItem": "{0} at {1}",
"selectBoardForInfo": "Please select a board to obtain board info.",
"platformMissing": "The platform for the selected '{0}' board is not installed.",
"selectPortForInfo": "Please select a port to obtain board info.",
"boardInfo": "Board Info",
"board": "Board{0}",
"port": "Port{0}",
"getBoardInfo": "Get Board Info",
"inSketchbook": " (in Sketchbook)"
},
"boardsManager": "Boards Manager",
"about": {
"label": "About {0}",
"detail": "Version: {0}\nDate: {1}{2}\nCLI Version: {3}{4} [{5}]\n\n{6}"
},
"contributions": {
"addFile": "Add File",
"replaceTitle": "Replace",
"fileAdded": "One file added to the sketch."
},
"replaceMsg": "Replace the existing version of {0}?",
"library": {
"addZip": "Add .ZIP Library...",
"zipLibrary": "Library",
"overwriteExistingLibrary": "Do you want to overwrite the existing library?",
"successfullyInstalledZipLibrary": "Successfully installed library from {0} archive",
"namedLibraryAlreadyExists": "A library folder named {0} already exists. Do you want to overwrite it?",
"libraryAlreadyExists": "A library already exists. Do you want to overwrite it?",
"include": "Include Library",
"manageLibraries": "Manage Libraries...",
"arduinoLibraries": "Arduino libraries",
"contributedLibraries": "Contributed libraries",
"title": "Library Manager",
"needsOneDependency": "The library <b>{0}:{1}</b> needs another dependency currently not installed:",
"needsMultipleDependencies": "The library <b>{0}:{1}</b> needs some other dependencies currently not installed:",
"installOneMissingDependency": "Would you like to install the missing dependency?",
"installMissingDependencies": "Would you like to install all the missing dependencies?",
"dependenciesForLibrary": "Dependencies for library {0}:{1}",
"installAll": "Install all",
"installOnly": "Install {0} only",
"installedSuccessfully": "Successfully installed library {0}:{1}",
"uninstalledSuccessfully": "Successfully uninstalled library {0}:{1}"
},
"selectZip": "Select a zip file containing the library you'd like to add",
"sketch": {
"archiveSketch": "Archive Sketch",
"saveSketchAs": "Save sketch folder as...",
"createdArchive": "Created archive '{0}'.",
"new": "New",
"openRecent": "Open Recent",
"showFolder": "Show Sketch Folder",
"sketch": "Sketch",
"moving": "Moving",
"movingMsg": "The file \"{0}\" needs to be inside a sketch folder named \"{1}\".\nCreate this folder, move the file, and continue?",
"cantOpen": "A folder named \"{0}\" already exists. Can't open sketch.",
"saveFolderAs": "Save sketch folder as...",
"sketchbook": "Sketchbook",
"upload": "Upload",
"uploadUsingProgrammer": "Upload Using Programmer",
"userFieldsNotFoundError": "Can't find user fields for connected board",
"doneUploading": "Done uploading.",
"configureAndUpload": "Configure And Upload",
"verifyOrCompile": "Verify/Compile",
"exportBinary": "Export Compiled Binary",
"verify": "Verify",
"doneCompiling": "Done compiling.",
"couldNotConnectToSerial": "Could not reconnect to serial port. {0}",
"openSketchInNewWindow": "Open Sketch in New Window",
"openFolder": "Open Folder",
"titleLocalSketchbook": "Local Sketchbook",
"titleSketchbook": "Sketchbook",
"close": "Are you sure you want to close the sketch?"
},
"bootloader": {
"burnBootloader": "Burn Bootloader",
"doneBurningBootloader": "Done burning bootloader."
},
"editor": {
"copyForForum": "Copy for Forum (Markdown)",
"commentUncomment": "Comment/Uncomment",
"increaseIndent": "Increase Indent",
"decreaseIndent": "Decrease Indent",
"increaseFontSize": "Increase Font Size",
"decreaseFontSize": "Decrease Font Size",
"autoFormat": "Auto Format"
},
"examples": {
"menu": "Examples",
"couldNotInitializeExamples": "Could not initialize built-in examples.",
"builtInExamples": "Built-in examples",
"customLibrary": "Examples from Custom Libraries",
"for": "Examples for {0}",
"forAny": "Examples for any board"
},
"help": {
"search": "Search on Arduino.cc",
"keyword": "Type a keyword",
"gettingStarted": "Getting Started",
"environment": "Environment",
"troubleshooting": "Troubleshooting",
"reference": "Reference",
"findInReference": "Find in Reference",
"faq": "Frequently Asked Questions",
"visit": "Visit Arduino.cc",
"privacyPolicy": "Privacy Policy"
},
"certificate": {
"uploadRootCertificates": "Upload SSL Root Certificates",
"openContext": "Open context",
"remove": "Remove",
"upload": "Upload",
"addURL": "Add URL to fetch SSL certificate",
"enterURL": "Enter URL",
"selectCertificateToUpload": "1. Select certificate to upload",
"addNew": "Add New",
"selectDestinationBoardToUpload": "2. Select destination board and upload certificate",
"uploadingCertificates": "Uploading certificates.",
"certificatesUploaded": "Certificates uploaded.",
"uploadFailed": "Upload failed. Please try again.",
"selectBoard": "Select a board...",
"boardAtPort": "{0} at {1}",
"noSupportedBoardConnected": "No supported board connected"
},
"firmware": {
"updater": "WiFi101 / WiFiNINA Firmware Updater",
"selectBoard": "Select Board",
"checkUpdates": "Check Updates",
"selectVersion": "Select firmware version",
"install": "Install",
"overwriteSketch": "Installation will overwrite the Sketch on the board.",
"installingFirmware": "Installing firmware.",
"successfullyInstalled": "Firmware successfully installed.",
"failedInstall": "Installation failed. Please try again."
},
"dialog": {
"dontAskAgain": "Don't ask again"
},
"userFields": {
"cancel": "Cancel",
"upload": "Upload"
},
"serial": {
"toggleTimestamp": "Toggle Timestamp",
"autoscroll": "Autoscroll",
"timestamp": "Timestamp",
"noLineEndings": "No Line Ending",
"newLine": "New Line",
"carriageReturn": "Carriage Return",
"newLineCarriageReturn": "Both NL & CR",
"notConnected": "Not connected. Select a board and a port to connect automatically.",
"message": "Message ({0} + Enter to send message to '{1}' on '{2}')",
"connectionBusy": "Connection failed. Serial port is busy: {0}",
"disconnected": "Disconnected {0} from {1}.",
"unexpectedError": "Unexpected error. Reconnecting {0} on port {1}.",
"failedReconnect": "Failed to reconnect {0} to serial port after 10 consecutive attempts. The {1} serial port is busy.",
"reconnect": "Reconnecting {0} to {1} in {2} seconds..."
},
"component": {
"uninstall": "Uninstall",
"uninstallMsg": "Do you want to uninstall {0}?",
"by": "by",
"version": "Version {0}",
"moreInfo": "More info",
"install": "INSTALL",
"filterSearch": "Filter your search..."
},
"electron": {
"couldNotSave": "Could not save the sketch. Please copy your unsaved work into your favorite text editor, and restart the IDE.",
"unsavedChanges": "Any unsaved changes will not be saved."
},
"compile": {
"error": "Compilation error: {0}"
},
"upload": {
"error": "{0} error: {1}"
},
"burnBootloader": {
"error": "Error while burning the bootloader: {0}"
}
},
"theia": {
"core": {
"couldNotSave": "Could not save the sketch. Please copy your unsaved work into your favorite text editor, and restart the IDE.",
"offline": "Offline",
"daemonOffline": "CLI Daemon Offline",
"cannotConnectBackend": "Cannot connect to the backend.",
"cannotConnectDaemon": "Cannot connect to the CLI daemon."
},
"debug": {
"start": "Start...",
"typeNotSupported": "The debug session type \"{0}\" is not supported.",
"startError": "There was an error starting the debug session, check the logs for more details."
},
"editor": {
"unsavedTitle": "Unsaved {0}"
},
"messages": {
"expand": "Expand",
"collapse": "Collapse"
},
"workspace": {
"fileNewName": "Name for new file",
"invalidFilename": "Invalid filename.",
"invalidExtension": ".{0} is not a valid extension",
"newFileName": "New name for file",
"deleteCurrentSketch": "Do you want to delete the current sketch?",
"sketchDirectoryError": "There was an error creating the sketch directory. See the log for more details. The application will probably not work as expected."
}
},
"cloud": {
"GoToCloud": "GO TO CLOUD"
}
}

350
i18n/sr.json Normal file
View File

@@ -0,0 +1,350 @@
{
"arduino": {
"common": {
"offlineIndicator": "Изгледа да сте ван мреже. Без интернет везе, Arduino CLI можда неће моћи да преузме потребне ресурсе и може изазвати квар. Повежите се на Интернет и поново покрените апликацију.",
"noBoardSelected": "Плоча није одабрана",
"selectedOn": "на {0}",
"notConnected": "[није повезано]",
"serialMonitor": "Монитор серијског порта",
"oldFormat": "The '{0}' still uses the old `.pde` format. Do you want to switch to the new `.ino` extension?",
"later": "Касније",
"selectBoard": "Одабери плочу",
"unknown": "Непознато",
"processing": "Обрађује се",
"saveChangesToSketch": "Да ли желиш да сачуваш рад прије затварања?",
"loseChanges": "Уколико не сачуваш, промјене ће бити изгубљене."
},
"ide-updater": {
"errorCheckingForUpdates": "Грешка приликом провере надоградњи за Arduino IDE.\n{0}",
"notNowButton": "Не сада",
"versionDownloaded": "Arduino IDE {0} је преузет.",
"closeToInstallNotice": "Затворите програм и покрените инсталацију надоградње на ваш рачунар.",
"closeAndInstallButton": "Затвори и инсталирај",
"downloadingNotice": "Преузимање последње верзије Arduino IDE.",
"updateAvailable": "Доступна је надоградња",
"newVersionAvailable": "Нова верзија Arduino IDE ({0}) је доступна за преузимање.",
"skipVersionButton": "Прескочите ову верзију",
"downloadButton": "Преузимање",
"goToDownloadPage": "Ажурирање за Arduine IDE је доступно, али нисмо у могућности да га аутоматски преузмемо и инсталирамо. Идите на страницу за преузимање и преузмите најновију верзију одатле.",
"goToDownloadButton": "Пређите на преузимање",
"ideUpdaterDialog": "Надоградња програма",
"noUpdatesAvailable": "Нема недавних доступних ажурирања за Arduine IDE"
},
"menu": {
"sketch": "Рад",
"tools": "Алатке"
},
"debug": {
"optimizeForDebugging": "Оптимизовано за отклањање грешака",
"debugWithMessage": "Отклањање грешака - {0}",
"noPlatformInstalledFor": "Платформа није инсталирана за '{0}'",
"debuggingNotSupported": "'{0}' не подржава отклањање грешака"
},
"preferences": {
"language.log": "Тачно ако Ардуино језички сервер треба да генерише датотеке евиденције у фасциклу за скице. Иначе, нетачно. Подразумевано је нетачно.",
"compile.verbose": "True for verbose compile output. False by default",
"compile.warnings": "Tells gcc which warning level to use. It's 'None' by default",
"upload.verbose": "True for verbose upload output. False by default.",
"window.autoScale": "True if the user interface automatically scales with the font size.",
"window.zoomLevel": "Подесите ниво зумирања прозора. Оригинална величина је 0 и сваки корак изнад (нпр. 1) или испод (нпр. -1) представља зумирање за 20% веће или мање. Такође можете да унесете децимале да бисте подесили ниво зумирања са бољом прецизношћу.",
"ide.updateChannel": "Release channel to get updated from. 'stable' is the stable release, 'nightly' is the latest development build.",
"board.certificates": "Листа сертификата који могу бити спуштени на плоче",
"sketchbook.showAllFiles": "True to show all sketch files inside the sketch. It is false by default.",
"cloud.enabled": "True if the sketch sync functions are enabled. Defaults to true.",
"cloud.pull.warn": "True if users should be warned before pulling a cloud sketch. Defaults to true.",
"cloud.push.warn": "True if users should be warned before pushing a cloud sketch. Defaults to true.",
"cloud.pushpublic.warn": "True if users should be warned before pushing a public sketch to the cloud. Defaults to true.",
"cloud.sketchSyncEnpoint": "The endpoint used to push and pull sketches from a backend. By default it points to Arduino Cloud API.",
"auth.clientID": "OAuth2 идентификатор клијента.",
"auth.domain": "OAuth2 домен.",
"auth.audience": "OAuth2 публика.",
"auth.registerUri": "URI коришћен за регистровање нових корисника.",
"network": "Мрежа",
"sketchbook.location": "Локација радне свеске",
"browse": "Претражи",
"files.inside.sketches": "Прикажи датотеке у радовима",
"editorFontSize": "Величина текста уређивача",
"interfaceScale": "Величина интерфејса",
"showVerbose": "Прикажи детаљан испис током",
"compilerWarnings": "Упозорења преводиоца",
"automatic": "Аутоматско",
"compile": "преведи",
"upload": "спусти",
"verifyAfterUpload": "Провјери код након спуштања",
"editorQuickSuggestions": "Editor Quick Suggestions",
"additionalManagerURLs": "Additional Boards Manager URLs",
"noProxy": "Без посредника",
"manualProxy": "Ручно подешавање посредника",
"newSketchbookLocation": "Одабери нову локацију радне свеске",
"choose": "Одабери",
"enterAdditionalURLs": "Enter additional URLs, one for each row",
"unofficialBoardSupport": "Click for a list of unofficial board support URLs",
"invalid.sketchbook.location": "Неважећа локација радне свеске: {0}",
"invalid.editorFontSize": "Неважећа величина текста уређивача. Мора да буде позитиван цијели број.",
"invalid.theme": "Неважећа тема."
},
"cloud": {
"signIn": "ПРИЈАВИ СЕ",
"signOut": "Одјави се",
"chooseSketchVisibility": "Одабери видљивост твог рада:",
"privateVisibility": "Приватно. Само ти можеш да видиш рад.",
"publicVisibility": "Јавно. Свако са линком може да види рад.",
"link": "Линк:",
"embed": "Угради:",
"cloudSketchbook": "Cloud Sketchbook",
"shareSketch": "Подјели рад",
"showHideRemoveSketchbook": "Прикажи/Сакриј удаљене радне свеске",
"pullSketch": "Pull Sketch",
"openInCloudEditor": "Open in Cloud Editor",
"options": "Опције...",
"share": "Подјели...",
"remote": "Удаљени",
"emptySketchbook": "Твоја радна свеска је празна",
"visitArduinoCloud": "Visit Arduino Cloud to create Cloud Sketches.",
"signInToCloud": "Улогујте се на Arduino Cloud",
"syncEditSketches": "Sync and edit your Arduino Cloud Sketches",
"learnMore": "Сазнајте више",
"continue": "Наставите",
"pushSketch": "Push Sketch",
"pushSketchMsg": "This is a Public Sketch. Before pushing, make sure any sensitive information is defined in arduino_secrets.h files. You can make a Sketch private from the Share panel.",
"pull": "Повуци",
"pullSketchMsg": "Pulling this Sketch from the Cloud will overwrite its local version. Are you sure you want to continue?",
"donePulling": "Готово повлачење {0}.",
"notYetPulled": "Cannot push to Cloud. It is not yet pulled.",
"push": "Гурни",
"pullFirst": "You have to pull first to be able to push to the Cloud.",
"donePushing": "Done pushing {0}.",
"connected": "Повезан",
"offline": "Није на мрежи",
"profilePicture": "Фотографија профила"
},
"board": {
"installManually": "Инсталирај ручно",
"installNow": "The \"{0} {1}\" core has to be installed for the currently selected \"{2}\" board. Do you want to install it now?",
"configDialogTitle": "Одабери другу плочу или порт",
"configDialog1": "Одабери и плочу и порт ако желиш да спустиш рад.",
"configDialog2": "Ако одабереш само плочу моћи ћеш само да преведеш, али не и да спустиш рад.",
"pleasePickBoard": "Одабери плочу повезану са одабраним портом.",
"showAllAvailablePorts": "Приказује све доступне портове када је укључено",
"programmer": "Програмер",
"succesfullyInstalledPlatform": "Успјешно инсталирана платформа {0}:{1}",
"succesfullyUninstalledPlatform": "Успјешно деинсталирана платформа {0}:{1}",
"couldNotFindPreviouslySelected": "Could not find previously selected board '{0}' in installed platform '{1}'. Please manually reselect the board you want to use. Do you want to reselect it now?",
"reselectLater": "Одабери поново касније",
"noneSelected": "Ниједна плоча није одабрана.",
"noPortsSelected": "Ниједан порт није одабран за плочу: '{0}'.",
"noFQBN": "The FQBN is not available for the selected board \"{0}\". Do you have the corresponding core installed?",
"openBoardsConfig": "Одабери другу плочу и порт...",
"boardListItem": "{0} на {1}",
"selectBoardForInfo": "Одабери плочу да добијеш информације о њој.",
"platformMissing": "Платформа за одабрану плочу '{0}' није инсталирана.",
"selectPortForInfo": "Одабери порт да добијеш информације о плочи",
"boardInfo": "Информације о плочи",
"board": "Плоча{0}",
"port": "Порт{0}",
"getBoardInfo": "Дохвати информације о плочи",
"inSketchbook": "(у радној свесци)"
},
"boardsManager": "Управљач плочама",
"about": {
"label": "О {0}",
"detail": "Верзија: {0}\nДатум: {1}{2}\nCLI верзија: {3}{4} [{5}]\n\n{6}"
},
"contributions": {
"addFile": "Додај датотеку",
"replaceTitle": "Замјени",
"fileAdded": "Датотека је додата у рад."
},
"replaceMsg": "Замјени тренутну верзију {0}?",
"library": {
"addZip": "Додај .ZIP библиотеку...",
"zipLibrary": "Библиотека",
"overwriteExistingLibrary": "Желиш да препишеш преко већ постојеће библиотеке?",
"successfullyInstalledZipLibrary": "Успјешно инсталирана библиотека из архиве {0}",
"namedLibraryAlreadyExists": "Директоријум за библиотеку назван {0} већ постоји. Желиш да препишеш преко њега?",
"libraryAlreadyExists": "Библиотека већ постоји. Желиш да препишеш преко ње?",
"include": "Укључи библиотеку",
"manageLibraries": "Управљај библиотекама...",
"arduinoLibraries": "Arduino библиотеке",
"contributedLibraries": "Contributed libraries",
"title": "Управљач библиотекама",
"needsOneDependency": "Библиотека <b>{0}:{1}</b> захтјева другу библиотеку која није тренутно инсталирана:",
"needsMultipleDependencies": "Библиотека <b>{0}:{1}</b> захтјева друге библиотеке које нису тренутно инсталиране:",
"installOneMissingDependency": "Да ли желиш да инсталираш зависну библиотеку?",
"installMissingDependencies": "Да ли желиш да инсталираш све зависне библиотеке?",
"dependenciesForLibrary": "Зависне библиотеке за библиотеку {0}:{1}",
"installAll": "Инсталирај све",
"installOnly": "Инсталирај само {0}",
"installedSuccessfully": "Успјешно инсталирана библиотека {0}:{1}",
"uninstalledSuccessfully": "Успјешно деинсталирана библиотека {0}:{1}"
},
"selectZip": "Одабери zip датотеку са библиотеком коју желиш да додаш",
"sketch": {
"archiveSketch": "Архивирај рад",
"saveSketchAs": "Сачувај радни фолдер као...",
"createdArchive": "Направљена архива '{0}'.",
"new": "Нови",
"openRecent": "Отвори недавно",
"showFolder": "Прикажи радни директоријум",
"sketch": "Рад",
"moving": "Премјешта се",
"movingMsg": "Датотека \"{0}\" мора да буде унутар радног директоријума \"{1}\".\nКреирај овај директоријум, премјести датотеку, и настави?",
"cantOpen": "Директоријум \"{0}\" већ постоји. Није могуће отворити рад.",
"saveFolderAs": "Сачувај радни директоријум као...",
"sketchbook": "Радна свеска",
"upload": "Спусти",
"uploadUsingProgrammer": "Спусти помоћу програмера",
"userFieldsNotFoundError": "Није могуће пронаћи корисничка поља за повезану плочу.",
"doneUploading": "Спуштање завршено.",
"configureAndUpload": "Конфигуриши и спусти",
"verifyOrCompile": "Провјери/Преведи",
"exportBinary": "Export Compiled Binary",
"verify": "Провјери",
"doneCompiling": "Превођење завршено.",
"couldNotConnectToSerial": "Could not reconnect to serial port. {0}",
"openSketchInNewWindow": "Отвори рад у новом прозору",
"openFolder": "Отвори директоријум",
"titleLocalSketchbook": "Локална радна свеска",
"titleSketchbook": "Радна свеска",
"close": "Да ли желиш да затвориш рад?"
},
"bootloader": {
"burnBootloader": "Burn Bootloader",
"doneBurningBootloader": "Done burning bootloader."
},
"editor": {
"copyForForum": "Копирај за форум (Markdown)",
"commentUncomment": "Коментариши/одкоментариши",
"increaseIndent": "Повећај увлачење",
"decreaseIndent": "Смањи увлачење",
"increaseFontSize": "Повећај величину текста",
"decreaseFontSize": "Смањи величину текста",
"autoFormat": "Аутоматски форматирај"
},
"examples": {
"menu": "Примјери",
"couldNotInitializeExamples": "Није могуће иницијализовати уграђене примјере.",
"builtInExamples": "Уграђени примјери",
"customLibrary": "Примјери библиотека",
"for": "Примјери за {0}",
"forAny": "Примјери за било коју плочу"
},
"help": {
"search": "Потражи на Arduino.cc",
"keyword": "Унеси кључну ријеч",
"gettingStarted": "Увод",
"environment": "Окружење",
"troubleshooting": "Рјешавање проблема",
"reference": "Референца",
"findInReference": "Потражи у референци",
"faq": "Често постављана питања",
"visit": "Посјети Arduino.cc",
"privacyPolicy": "Политика приватности"
},
"certificate": {
"uploadRootCertificates": "Спусти SSL Root сертификате",
"openContext": "Отвори садржај",
"remove": "Избаци",
"upload": "Спусти",
"addURL": "Додај URL за дохватање SSL сертификата",
"enterURL": "Унеси URL",
"selectCertificateToUpload": "1. Одабери сертификат за спуштање",
"addNew": "Додај нови",
"selectDestinationBoardToUpload": "2. Одабери одредишну плочу и спусти сертификат",
"uploadingCertificates": "Спуштање сертификата.",
"certificatesUploaded": "Сертификати су спуштени.",
"uploadFailed": "Спуштање није успјело. Покушај поново.",
"selectBoard": "Одабери плочу...",
"boardAtPort": "{0} на {1}",
"noSupportedBoardConnected": "Није повезана ниједна подржана плоча"
},
"firmware": {
"updater": "WiFi101 / WiFiNINA Firmware Updater",
"selectBoard": "Одабери плочу",
"checkUpdates": "Провјери ажурирања",
"selectVersion": "Одаберзи верзију фирмвера",
"install": "Инсталирај",
"overwriteSketch": "Инсталација ће преписати рад на плочи.",
"installingFirmware": "Инсталирање фирмвера.",
"successfullyInstalled": "Фирмвер успјешно инсталиран.",
"failedInstall": "Инсталирање није успјело. Покушај поново."
},
"dialog": {
"dontAskAgain": "Не питај поново"
},
"userFields": {
"cancel": "Одустани",
"upload": "Спусти"
},
"serial": {
"toggleTimestamp": "Укључи/искључи временску ознаку",
"autoscroll": "Аутоматско скроловање",
"timestamp": "Временска ознака",
"noLineEndings": "Без завршетка линије",
"newLine": "Нова линија",
"carriageReturn": "Carriage Return",
"newLineCarriageReturn": "И нова линија и CR",
"notConnected": "Није повезано. Одабери плочу и порт за аутоматско повезивање.",
"message": "Message ({0} + Enter to send message to '{1}' on '{2}')",
"connectionBusy": "Повезивање није успјело. Серијски порт је заузет: {0}",
"disconnected": "Откачен {0} од {1}.",
"unexpectedError": "Неочекивана грешка. Поновно повезивање {0} на порту {1}.",
"failedReconnect": "Failed to reconnect {0} to serial port after 10 consecutive attempts. The {1} serial port is busy.",
"reconnect": "Поновно повезивање {0} на {1} за {2} секунди..."
},
"component": {
"uninstall": "Деинсталирај",
"uninstallMsg": "Да ли желиш да деинсталираш {0}? ",
"by": "од",
"version": "Верзија {0}",
"moreInfo": "Више информација",
"install": "ИНСТАЛИРАЈ",
"filterSearch": "Филтрирај претрагу..."
},
"electron": {
"couldNotSave": "Could not save the sketch. Please copy your unsaved work into your favorite text editor, and restart the IDE.",
"unsavedChanges": "Ниједна несачувана промјена неће бити сачувана."
},
"compile": {
"error": "Грешка приликом превођења: {0}"
},
"upload": {
"error": "{0} грешка: {1}"
},
"burnBootloader": {
"error": "Error while burning the bootloader: {0}"
}
},
"theia": {
"core": {
"couldNotSave": "Could not save the sketch. Please copy your unsaved work into your favorite text editor, and restart the IDE.",
"offline": "Није на мрежи",
"daemonOffline": "CLI Daemon Offline",
"cannotConnectBackend": "Cannot connect to the backend.",
"cannotConnectDaemon": "Cannot connect to the CLI daemon."
},
"debug": {
"start": "Почни...",
"typeNotSupported": "The debug session type \"{0}\" is not supported.",
"startError": "There was an error starting the debug session, check the logs for more details."
},
"editor": {
"unsavedTitle": "Несачуван {0} "
},
"messages": {
"expand": "Прошири",
"collapse": "Отвори"
},
"workspace": {
"fileNewName": "Име за нову датотеку",
"invalidFilename": "Неважеће име датотеке.",
"invalidExtension": ".{0} није валидна екстензија",
"newFileName": "Ново име за датотеку",
"deleteCurrentSketch": "Да ли желиш да обришеш тренутни рад?",
"sketchDirectoryError": "There was an error creating the sketch directory. See the log for more details. The application will probably not work as expected."
}
},
"cloud": {
"GoToCloud": "GO TO CLOUD"
}
}

350
i18n/ta.json Normal file
View File

@@ -0,0 +1,350 @@
{
"arduino": {
"common": {
"offlineIndicator": "You appear to be offline. Without an Internet connection, the Arduino CLI might not be able to download the required resources and could cause malfunction. Please connect to the Internet and restart the application.",
"noBoardSelected": "No board selected",
"selectedOn": "on {0}",
"notConnected": "[not connected]",
"serialMonitor": "Serial Monitor",
"oldFormat": "The '{0}' still uses the old `.pde` format. Do you want to switch to the new `.ino` extension?",
"later": "Later",
"selectBoard": "Select Board",
"unknown": "Unknown",
"processing": "Processing",
"saveChangesToSketch": "Do you want to save changes to this sketch before closing?",
"loseChanges": "If you don't save, your changes will be lost."
},
"ide-updater": {
"errorCheckingForUpdates": "Error while checking for Arduino IDE updates.\n{0}",
"notNowButton": "Not now",
"versionDownloaded": "Arduino IDE {0} has been downloaded.",
"closeToInstallNotice": "Close the software and install the update on your machine.",
"closeAndInstallButton": "Close and Install",
"downloadingNotice": "Downloading the latest version of the Arduino IDE.",
"updateAvailable": "Update Available",
"newVersionAvailable": "A new version of Arduino IDE ({0}) is available for download.",
"skipVersionButton": "Skip Version",
"downloadButton": "Download",
"goToDownloadPage": "An update for the Arduino IDE is available, but we're not able to download and install it automatically. Please go to the download page and download the latest version from there.",
"goToDownloadButton": "Go To Download",
"ideUpdaterDialog": "Software Update",
"noUpdatesAvailable": "There are no recent updates available for the Arduino IDE"
},
"menu": {
"sketch": "Sketch",
"tools": "Tools"
},
"debug": {
"optimizeForDebugging": "Optimize for Debugging",
"debugWithMessage": "Debug - {0}",
"noPlatformInstalledFor": "Platform is not installed for '{0}'",
"debuggingNotSupported": "Debugging is not supported by '{0}'"
},
"preferences": {
"language.log": "True if the Arduino Language Server should generate log files into the sketch folder. Otherwise, false. It's false by default.",
"compile.verbose": "True for verbose compile output. False by default",
"compile.warnings": "Tells gcc which warning level to use. It's 'None' by default",
"upload.verbose": "True for verbose upload output. False by default.",
"window.autoScale": "True if the user interface automatically scales with the font size.",
"window.zoomLevel": "Adjust the zoom level of the window. The original size is 0 and each increment above (e.g. 1) or below (e.g. -1) represents zooming 20% larger or smaller. You can also enter decimals to adjust the zoom level with a finer granularity.",
"ide.updateChannel": "Release channel to get updated from. 'stable' is the stable release, 'nightly' is the latest development build.",
"board.certificates": "List of certificates that can be uploaded to boards",
"sketchbook.showAllFiles": "True to show all sketch files inside the sketch. It is false by default.",
"cloud.enabled": "True if the sketch sync functions are enabled. Defaults to true.",
"cloud.pull.warn": "True if users should be warned before pulling a cloud sketch. Defaults to true.",
"cloud.push.warn": "True if users should be warned before pushing a cloud sketch. Defaults to true.",
"cloud.pushpublic.warn": "True if users should be warned before pushing a public sketch to the cloud. Defaults to true.",
"cloud.sketchSyncEnpoint": "The endpoint used to push and pull sketches from a backend. By default it points to Arduino Cloud API.",
"auth.clientID": "The OAuth2 client ID.",
"auth.domain": "The OAuth2 domain.",
"auth.audience": "The OAuth2 audience.",
"auth.registerUri": "The URI used to register a new user.",
"network": "Network",
"sketchbook.location": "Sketchbook location",
"browse": "Browse",
"files.inside.sketches": "Show files inside Sketches",
"editorFontSize": "Editor font size",
"interfaceScale": "Interface scale",
"showVerbose": "Show verbose output during",
"compilerWarnings": "Compiler warnings",
"automatic": "Automatic",
"compile": "compile",
"upload": "upload",
"verifyAfterUpload": "Verify code after upload",
"editorQuickSuggestions": "Editor Quick Suggestions",
"additionalManagerURLs": "Additional Boards Manager URLs",
"noProxy": "No proxy",
"manualProxy": "Manual proxy configuration",
"newSketchbookLocation": "Select new sketchbook location",
"choose": "Choose",
"enterAdditionalURLs": "Enter additional URLs, one for each row",
"unofficialBoardSupport": "Click for a list of unofficial board support URLs",
"invalid.sketchbook.location": "Invalid sketchbook location: {0}",
"invalid.editorFontSize": "Invalid editor font size. It must be a positive integer.",
"invalid.theme": "Invalid theme."
},
"cloud": {
"signIn": "SIGN IN",
"signOut": "Sign Out",
"chooseSketchVisibility": "Choose visibility of your Sketch:",
"privateVisibility": "Private. Only you can view the Sketch.",
"publicVisibility": "Public. Anyone with the link can view the Sketch.",
"link": "Link:",
"embed": "Embed:",
"cloudSketchbook": "Cloud Sketchbook",
"shareSketch": "Share Sketch",
"showHideRemoveSketchbook": "Show/Hide Remote Sketchbook",
"pullSketch": "Pull Sketch",
"openInCloudEditor": "Open in Cloud Editor",
"options": "Options...",
"share": "Share...",
"remote": "Remote",
"emptySketchbook": "Your Sketchbook is empty",
"visitArduinoCloud": "Visit Arduino Cloud to create Cloud Sketches.",
"signInToCloud": "Sign in to Arduino Cloud",
"syncEditSketches": "Sync and edit your Arduino Cloud Sketches",
"learnMore": "Learn more",
"continue": "Continue",
"pushSketch": "Push Sketch",
"pushSketchMsg": "This is a Public Sketch. Before pushing, make sure any sensitive information is defined in arduino_secrets.h files. You can make a Sketch private from the Share panel.",
"pull": "Pull",
"pullSketchMsg": "Pulling this Sketch from the Cloud will overwrite its local version. Are you sure you want to continue?",
"donePulling": "Done pulling {0}.",
"notYetPulled": "Cannot push to Cloud. It is not yet pulled.",
"push": "Push",
"pullFirst": "You have to pull first to be able to push to the Cloud.",
"donePushing": "Done pushing {0}.",
"connected": "Connected",
"offline": "Offline",
"profilePicture": "Profile picture"
},
"board": {
"installManually": "Install Manually",
"installNow": "The \"{0} {1}\" core has to be installed for the currently selected \"{2}\" board. Do you want to install it now?",
"configDialogTitle": "Select Other Board & Port",
"configDialog1": "Select both a Board and a Port if you want to upload a sketch.",
"configDialog2": "If you only select a Board you will be able to compile, but not to upload your sketch.",
"pleasePickBoard": "Please pick a board connected to the port you have selected.",
"showAllAvailablePorts": "Shows all available ports when enabled",
"programmer": "Programmer",
"succesfullyInstalledPlatform": "Successfully installed platform {0}:{1}",
"succesfullyUninstalledPlatform": "Successfully uninstalled platform {0}:{1}",
"couldNotFindPreviouslySelected": "Could not find previously selected board '{0}' in installed platform '{1}'. Please manually reselect the board you want to use. Do you want to reselect it now?",
"reselectLater": "Reselect later",
"noneSelected": "No boards selected.",
"noPortsSelected": "No ports selected for board: '{0}'.",
"noFQBN": "The FQBN is not available for the selected board \"{0}\". Do you have the corresponding core installed?",
"openBoardsConfig": "Select other board and port…",
"boardListItem": "{0} at {1}",
"selectBoardForInfo": "Please select a board to obtain board info.",
"platformMissing": "The platform for the selected '{0}' board is not installed.",
"selectPortForInfo": "Please select a port to obtain board info.",
"boardInfo": "Board Info",
"board": "Board{0}",
"port": "Port{0}",
"getBoardInfo": "Get Board Info",
"inSketchbook": " (in Sketchbook)"
},
"boardsManager": "Boards Manager",
"about": {
"label": "About {0}",
"detail": "Version: {0}\nDate: {1}{2}\nCLI Version: {3}{4} [{5}]\n\n{6}"
},
"contributions": {
"addFile": "Add File",
"replaceTitle": "Replace",
"fileAdded": "One file added to the sketch."
},
"replaceMsg": "Replace the existing version of {0}?",
"library": {
"addZip": "Add .ZIP Library...",
"zipLibrary": "Library",
"overwriteExistingLibrary": "Do you want to overwrite the existing library?",
"successfullyInstalledZipLibrary": "Successfully installed library from {0} archive",
"namedLibraryAlreadyExists": "A library folder named {0} already exists. Do you want to overwrite it?",
"libraryAlreadyExists": "A library already exists. Do you want to overwrite it?",
"include": "Include Library",
"manageLibraries": "Manage Libraries...",
"arduinoLibraries": "Arduino libraries",
"contributedLibraries": "Contributed libraries",
"title": "Library Manager",
"needsOneDependency": "The library <b>{0}:{1}</b> needs another dependency currently not installed:",
"needsMultipleDependencies": "The library <b>{0}:{1}</b> needs some other dependencies currently not installed:",
"installOneMissingDependency": "Would you like to install the missing dependency?",
"installMissingDependencies": "Would you like to install all the missing dependencies?",
"dependenciesForLibrary": "Dependencies for library {0}:{1}",
"installAll": "Install all",
"installOnly": "Install {0} only",
"installedSuccessfully": "Successfully installed library {0}:{1}",
"uninstalledSuccessfully": "Successfully uninstalled library {0}:{1}"
},
"selectZip": "Select a zip file containing the library you'd like to add",
"sketch": {
"archiveSketch": "Archive Sketch",
"saveSketchAs": "Save sketch folder as...",
"createdArchive": "Created archive '{0}'.",
"new": "New",
"openRecent": "Open Recent",
"showFolder": "Show Sketch Folder",
"sketch": "Sketch",
"moving": "Moving",
"movingMsg": "The file \"{0}\" needs to be inside a sketch folder named \"{1}\".\nCreate this folder, move the file, and continue?",
"cantOpen": "A folder named \"{0}\" already exists. Can't open sketch.",
"saveFolderAs": "Save sketch folder as...",
"sketchbook": "Sketchbook",
"upload": "Upload",
"uploadUsingProgrammer": "Upload Using Programmer",
"userFieldsNotFoundError": "Can't find user fields for connected board",
"doneUploading": "Done uploading.",
"configureAndUpload": "Configure And Upload",
"verifyOrCompile": "Verify/Compile",
"exportBinary": "Export Compiled Binary",
"verify": "Verify",
"doneCompiling": "Done compiling.",
"couldNotConnectToSerial": "Could not reconnect to serial port. {0}",
"openSketchInNewWindow": "Open Sketch in New Window",
"openFolder": "Open Folder",
"titleLocalSketchbook": "Local Sketchbook",
"titleSketchbook": "Sketchbook",
"close": "Are you sure you want to close the sketch?"
},
"bootloader": {
"burnBootloader": "Burn Bootloader",
"doneBurningBootloader": "Done burning bootloader."
},
"editor": {
"copyForForum": "Copy for Forum (Markdown)",
"commentUncomment": "Comment/Uncomment",
"increaseIndent": "Increase Indent",
"decreaseIndent": "Decrease Indent",
"increaseFontSize": "Increase Font Size",
"decreaseFontSize": "Decrease Font Size",
"autoFormat": "Auto Format"
},
"examples": {
"menu": "Examples",
"couldNotInitializeExamples": "Could not initialize built-in examples.",
"builtInExamples": "Built-in examples",
"customLibrary": "Examples from Custom Libraries",
"for": "Examples for {0}",
"forAny": "Examples for any board"
},
"help": {
"search": "Search on Arduino.cc",
"keyword": "Type a keyword",
"gettingStarted": "Getting Started",
"environment": "Environment",
"troubleshooting": "Troubleshooting",
"reference": "Reference",
"findInReference": "Find in Reference",
"faq": "Frequently Asked Questions",
"visit": "Visit Arduino.cc",
"privacyPolicy": "Privacy Policy"
},
"certificate": {
"uploadRootCertificates": "Upload SSL Root Certificates",
"openContext": "Open context",
"remove": "Remove",
"upload": "Upload",
"addURL": "Add URL to fetch SSL certificate",
"enterURL": "Enter URL",
"selectCertificateToUpload": "1. Select certificate to upload",
"addNew": "Add New",
"selectDestinationBoardToUpload": "2. Select destination board and upload certificate",
"uploadingCertificates": "Uploading certificates.",
"certificatesUploaded": "Certificates uploaded.",
"uploadFailed": "Upload failed. Please try again.",
"selectBoard": "Select a board...",
"boardAtPort": "{0} at {1}",
"noSupportedBoardConnected": "No supported board connected"
},
"firmware": {
"updater": "WiFi101 / WiFiNINA Firmware Updater",
"selectBoard": "Select Board",
"checkUpdates": "Check Updates",
"selectVersion": "Select firmware version",
"install": "Install",
"overwriteSketch": "Installation will overwrite the Sketch on the board.",
"installingFirmware": "Installing firmware.",
"successfullyInstalled": "Firmware successfully installed.",
"failedInstall": "Installation failed. Please try again."
},
"dialog": {
"dontAskAgain": "Don't ask again"
},
"userFields": {
"cancel": "Cancel",
"upload": "Upload"
},
"serial": {
"toggleTimestamp": "Toggle Timestamp",
"autoscroll": "Autoscroll",
"timestamp": "Timestamp",
"noLineEndings": "No Line Ending",
"newLine": "New Line",
"carriageReturn": "Carriage Return",
"newLineCarriageReturn": "Both NL & CR",
"notConnected": "Not connected. Select a board and a port to connect automatically.",
"message": "Message ({0} + Enter to send message to '{1}' on '{2}')",
"connectionBusy": "Connection failed. Serial port is busy: {0}",
"disconnected": "Disconnected {0} from {1}.",
"unexpectedError": "Unexpected error. Reconnecting {0} on port {1}.",
"failedReconnect": "Failed to reconnect {0} to serial port after 10 consecutive attempts. The {1} serial port is busy.",
"reconnect": "Reconnecting {0} to {1} in {2} seconds..."
},
"component": {
"uninstall": "Uninstall",
"uninstallMsg": "Do you want to uninstall {0}?",
"by": "by",
"version": "Version {0}",
"moreInfo": "More info",
"install": "INSTALL",
"filterSearch": "Filter your search..."
},
"electron": {
"couldNotSave": "Could not save the sketch. Please copy your unsaved work into your favorite text editor, and restart the IDE.",
"unsavedChanges": "Any unsaved changes will not be saved."
},
"compile": {
"error": "Compilation error: {0}"
},
"upload": {
"error": "{0} error: {1}"
},
"burnBootloader": {
"error": "Error while burning the bootloader: {0}"
}
},
"theia": {
"core": {
"couldNotSave": "Could not save the sketch. Please copy your unsaved work into your favorite text editor, and restart the IDE.",
"offline": "Offline",
"daemonOffline": "CLI Daemon Offline",
"cannotConnectBackend": "Cannot connect to the backend.",
"cannotConnectDaemon": "Cannot connect to the CLI daemon."
},
"debug": {
"start": "Start...",
"typeNotSupported": "The debug session type \"{0}\" is not supported.",
"startError": "There was an error starting the debug session, check the logs for more details."
},
"editor": {
"unsavedTitle": "Unsaved {0}"
},
"messages": {
"expand": "Expand",
"collapse": "Collapse"
},
"workspace": {
"fileNewName": "Name for new file",
"invalidFilename": "Invalid filename.",
"invalidExtension": ".{0} is not a valid extension",
"newFileName": "New name for file",
"deleteCurrentSketch": "Do you want to delete the current sketch?",
"sketchDirectoryError": "There was an error creating the sketch directory. See the log for more details. The application will probably not work as expected."
}
},
"cloud": {
"GoToCloud": "GO TO CLOUD"
}
}

View File

@@ -1,125 +1,125 @@
{ {
"arduino": { "arduino": {
"common": { "common": {
"offlineIndicator": "You appear to be offline. Without an Internet connection, the Arduino CLI might not be able to download the required resources and could cause malfunction. Please connect to the Internet and restart the application.", "offlineIndicator": "您目前處於離線狀態在沒有網路的情況下Arduino命令列介面將無法下載需要的資源並可能導致錯誤。請連接至網路並重新啟動程式。",
"noBoardSelected": "沒有選擇開發版", "noBoardSelected": "沒有選擇開發版",
"selectedOn": "on {0}", "selectedOn": "on {0}",
"notConnected": "[未連接]", "notConnected": "[未連接]",
"serialMonitor": "序列埠監控", "serialMonitor": "序列埠監控",
"oldFormat": "The '{0}' still uses the old `.pde` format. Do you want to switch to the new `.ino` extension?", "oldFormat": "'{0}'仍然使用舊的 `.pde` 格式,是否要轉換至新的 `.ino` 擴充?",
"later": "Later", "later": "稍後再說",
"selectBoard": "選擇開發版", "selectBoard": "選擇開發版",
"unknown": "未知", "unknown": "未知",
"processing": "Processing", "processing": "資料處理中",
"saveChangesToSketch": "Do you want to save changes to this sketch before closing?", "saveChangesToSketch": "是否在關閉草稿前儲存變更?",
"loseChanges": "If you don't save, your changes will be lost." "loseChanges": "如果不儲存,所做的變更將會遺失。"
}, },
"ide-updater": { "ide-updater": {
"errorCheckingForUpdates": "Error while checking for Arduino IDE updates.\n{0}", "errorCheckingForUpdates": "檢查Arduino IDE更新時發生錯誤。{0}",
"notNowButton": "現在不要", "notNowButton": "現在不要",
"versionDownloaded": "Arduino IDE {0} has been downloaded.", "versionDownloaded": "Arduino IDE{0}下載完成。",
"closeToInstallNotice": "Close the software and install the update on your machine.", "closeToInstallNotice": "關閉軟體並安裝更新。",
"closeAndInstallButton": "Close and Install", "closeAndInstallButton": "關閉並安裝。",
"downloadingNotice": "Downloading the latest version of the Arduino IDE.", "downloadingNotice": "正在下載最新版本的Arduino IDE",
"updateAvailable": "Update Available", "updateAvailable": "有可用的更新。",
"newVersionAvailable": "A new version of Arduino IDE ({0}) is available for download.", "newVersionAvailable": "有新版本的Arduino IDE({0})可供下載。",
"skipVersionButton": "Skip Version", "skipVersionButton": "跳過這個版本",
"downloadButton": "Download", "downloadButton": "下載",
"goToDownloadPage": "An update for the Arduino IDE is available, but we're not able to download and install it automatically. Please go to the download page and download the latest version from there.", "goToDownloadPage": "Arduino IDE可以更新但我們無法自動下載與安裝。請至下載頁面下載最新的版本。",
"goToDownloadButton": "Go To Download", "goToDownloadButton": "前往下載",
"ideUpdaterDialog": "Software Update", "ideUpdaterDialog": "軟體更新",
"noUpdatesAvailable": "There are no recent updates available for the Arduino IDE" "noUpdatesAvailable": "Arduino IDE目前沒有更新的版本。"
}, },
"menu": { "menu": {
"sketch": "Sketch", "sketch": "草稿",
"tools": "Tools" "tools": "工具"
}, },
"debug": { "debug": {
"optimizeForDebugging": "Optimize for Debugging", "optimizeForDebugging": "除錯最佳化",
"debugWithMessage": "Debug - {0}", "debugWithMessage": "除錯 - {0}",
"noPlatformInstalledFor": "Platform is not installed for '{0}'", "noPlatformInstalledFor": "未安裝'{0}'的平台",
"debuggingNotSupported": "Debugging is not supported by '{0}'" "debuggingNotSupported": "'{0}'不支援除錯。"
}, },
"preferences": { "preferences": {
"language.log": "True if the Arduino Language Server should generate log files into the sketch folder. Otherwise, false. It's false by default.", "language.log": "True則Arduino語言伺服器會自動在草稿資料夾產生日誌檔案。預設為false。",
"compile.verbose": "True for verbose compile output. False by default", "compile.verbose": "True則輸出詳細編譯資訊。預設為False",
"compile.warnings": "Tells gcc which warning level to use. It's 'None' by default", "compile.warnings": "設定gcc警告等級。預設為'None'",
"upload.verbose": "True for verbose upload output. False by default.", "upload.verbose": "True則輸出詳細上傳資訊。預設為False",
"window.autoScale": "True if the user interface automatically scales with the font size.", "window.autoScale": "True則使用者介面隨字體大小自動縮放。",
"window.zoomLevel": "Adjust the zoom level of the window. The original size is 0 and each increment above (e.g. 1) or below (e.g. -1) represents zooming 20% larger or smaller. You can also enter decimals to adjust the zoom level with a finer granularity.", "window.zoomLevel": "調整視窗的縮放大小。預設大小為0增加(例如1)或者減少(例如-1)代表縮放增加或減少20%。可以自行輸入小數調整更精細的大小。",
"ide.updateChannel": "Release channel to get updated from. 'stable' is the stable release, 'nightly' is the latest development build.", "ide.updateChannel": "前往版本釋出頻道獲取更新。 'stable'表示為穩定的版本, 'nightly' 則是最新的開發版本。",
"board.certificates": "List of certificates that can be uploaded to boards", "board.certificates": "可上傳至開發版的證書列表",
"sketchbook.showAllFiles": "True to show all sketch files inside the sketch. It is false by default.", "sketchbook.showAllFiles": "True則顯示所有草稿中的草稿檔案。預設為false。",
"cloud.enabled": "True if the sketch sync functions are enabled. Defaults to true.", "cloud.enabled": "True則啟用草稿同步功能。預設為true",
"cloud.pull.warn": "True if users should be warned before pulling a cloud sketch. Defaults to true.", "cloud.pull.warn": "True則在取出雲端草稿時警告使用者。預設為true",
"cloud.push.warn": "True if users should be warned before pushing a cloud sketch. Defaults to true.", "cloud.push.warn": "True則在更改雲端草稿時警告使用者。預設為True",
"cloud.pushpublic.warn": "True if users should be warned before pushing a public sketch to the cloud. Defaults to true.", "cloud.pushpublic.warn": "True則在更改一個公開草稿到雲端時警告使用者。預設為true",
"cloud.sketchSyncEnpoint": "The endpoint used to push and pull sketches from a backend. By default it points to Arduino Cloud API.", "cloud.sketchSyncEnpoint": "用來從後台更改與取出草稿的端點。預設的端點是指向Arduino Cloud API",
"auth.clientID": "The OAuth2 client ID.", "auth.clientID": "OAuth2客戶端ID",
"auth.domain": "The OAuth2 domain.", "auth.domain": "OAuth2",
"auth.audience": "The OAuth2 audience.", "auth.audience": "OAuth2閱聽者",
"auth.registerUri": "The URI used to register a new user.", "auth.registerUri": "用於註冊新使用者的地址",
"network": "Network", "network": "網路",
"sketchbook.location": "Sketchbook location", "sketchbook.location": "草稿資料夾位置",
"browse": "Browse", "browse": "瀏覽",
"files.inside.sketches": "Show files inside Sketches", "files.inside.sketches": "顯示草稿中的檔案",
"editorFontSize": "Editor font size", "editorFontSize": "編輯器字體大小",
"interfaceScale": "Interface scale", "interfaceScale": "介面比例",
"showVerbose": "Show verbose output during", "showVerbose": "顯示詳細輸出",
"compilerWarnings": "Compiler warnings", "compilerWarnings": "編譯器警告",
"automatic": "Automatic", "automatic": "自動調整",
"compile": "compile", "compile": "編譯",
"upload": "upload", "upload": "上傳",
"verifyAfterUpload": "Verify code after upload", "verifyAfterUpload": "上傳後驗證程式",
"editorQuickSuggestions": "Editor Quick Suggestions", "editorQuickSuggestions": "編輯器快速建議",
"additionalManagerURLs": "Additional Boards Manager URLs", "additionalManagerURLs": "其他開發版管理器網址",
"noProxy": "No proxy", "noProxy": "無代理",
"manualProxy": "Manual proxy configuration", "manualProxy": "手動設置代理",
"newSketchbookLocation": "Select new sketchbook location", "newSketchbookLocation": "選取新的草稿資料夾位置",
"choose": "Choose", "choose": "選擇",
"enterAdditionalURLs": "Enter additional URLs, one for each row", "enterAdditionalURLs": "輸入其他網址,每行一個",
"unofficialBoardSupport": "Click for a list of unofficial board support URLs", "unofficialBoardSupport": "點擊以取得支援非官方開發版的網址列表",
"invalid.sketchbook.location": "Invalid sketchbook location: {0}", "invalid.sketchbook.location": "無效的草稿資料夾位置:{0}",
"invalid.editorFontSize": "Invalid editor font size. It must be a positive integer.", "invalid.editorFontSize": "無效的編輯器字體大小。它必須是正整數。",
"invalid.theme": "Invalid theme." "invalid.theme": "無效的主題。"
}, },
"cloud": { "cloud": {
"signIn": "SIGN IN", "signIn": "登入",
"signOut": "Sign Out", "signOut": "登出",
"chooseSketchVisibility": "Choose visibility of your Sketch:", "chooseSketchVisibility": "選擇草稿的能見度:",
"privateVisibility": "Private. Only you can view the Sketch.", "privateVisibility": "私人的。只有你可以查看草稿。",
"publicVisibility": "Public. Anyone with the link can view the Sketch.", "publicVisibility": "公開的。擁有連結的人都可以查看草稿。",
"link": "Link:", "link": "連結:",
"embed": "Embed:", "embed": "嵌入:",
"cloudSketchbook": "Cloud Sketchbook", "cloudSketchbook": "雲端草稿資料夾",
"shareSketch": "Share Sketch", "shareSketch": "分享草稿",
"showHideRemoveSketchbook": "Show/Hide Remote Sketchbook", "showHideRemoveSketchbook": "顯示/隱藏遠端草稿資料夾",
"pullSketch": "Pull Sketch", "pullSketch": "讀取草稿",
"openInCloudEditor": "Open in Cloud Editor", "openInCloudEditor": "在雲端編輯器中打開",
"options": "Options...", "options": "選項...",
"share": "Share...", "share": "分享...",
"remote": "Remote", "remote": "遠端",
"emptySketchbook": "Your Sketchbook is empty", "emptySketchbook": "您的草稿資料夾是空的",
"visitArduinoCloud": "Visit Arduino Cloud to create Cloud Sketches.", "visitArduinoCloud": "前往Arduino Cloud建立雲端草稿。",
"signInToCloud": "Sign in to Arduino Cloud", "signInToCloud": "登入Arduino Cloud",
"syncEditSketches": "Sync and edit your Arduino Cloud Sketches", "syncEditSketches": "同步和編輯您的Arduino Clou草稿",
"learnMore": "Learn more", "learnMore": "了解更多",
"continue": "Continue", "continue": "繼續",
"pushSketch": "Push Sketch", "pushSketch": "更改草稿",
"pushSketchMsg": "This is a Public Sketch. Before pushing, make sure any sensitive information is defined in arduino_secrets.h files. You can make a Sketch private from the Share panel.", "pushSketchMsg": "這是一個公開草稿在更改前請確認所有敏感資訊都定義在arduino_secrets.h中。可以在分享介面設定為私人草稿。",
"pull": "Pull", "pull": "讀取",
"pullSketchMsg": "Pulling this Sketch from the Cloud will overwrite its local version. Are you sure you want to continue?", "pullSketchMsg": "從雲端中讀取這個草稿將會覆蓋本地的版本。你確定要繼續嗎?",
"donePulling": "Done pulling {0}.", "donePulling": "完成讀取'{0}'。",
"notYetPulled": "Cannot push to Cloud. It is not yet pulled.", "notYetPulled": "無法更改至雲端。尚未被讀取。",
"push": "Push", "push": "更改",
"pullFirst": "You have to pull first to be able to push to the Cloud.", "pullFirst": "您必些先讀取才能更改至Cloud",
"donePushing": "Done pushing {0}.", "donePushing": "完成更改'{0}'。",
"connected": "Connected", "connected": "已連接",
"offline": "Offline", "offline": "離線",
"profilePicture": "Profile picture" "profilePicture": "頭像圖片"
}, },
"board": { "board": {
"installManually": "Install Manually", "installManually": "手動安裝",
"installNow": "The \"{0} {1}\" core has to be installed for the currently selected \"{2}\" board. Do you want to install it now?", "installNow": "The \"{0} {1}\" core has to be installed for the currently selected \"{2}\" board. Do you want to install it now?",
"configDialogTitle": "Select Other Board & Port", "configDialogTitle": "Select Other Board & Port",
"configDialog1": "Select both a Board and a Port if you want to upload a sketch.", "configDialog1": "Select both a Board and a Port if you want to upload a sketch.",
@@ -186,7 +186,7 @@
"new": "新增", "new": "新增",
"openRecent": "Open Recent", "openRecent": "Open Recent",
"showFolder": "Show Sketch Folder", "showFolder": "Show Sketch Folder",
"sketch": "Sketch", "sketch": "草稿",
"moving": "Moving", "moving": "Moving",
"movingMsg": "The file \"{0}\" needs to be inside a sketch folder named \"{1}\".\nCreate this folder, move the file, and continue?", "movingMsg": "The file \"{0}\" needs to be inside a sketch folder named \"{1}\".\nCreate this folder, move the file, and continue?",
"cantOpen": "A folder named \"{0}\" already exists. Can't open sketch.", "cantOpen": "A folder named \"{0}\" already exists. Can't open sketch.",
@@ -318,7 +318,7 @@
"theia": { "theia": {
"core": { "core": {
"couldNotSave": "Could not save the sketch. Please copy your unsaved work into your favorite text editor, and restart the IDE.", "couldNotSave": "Could not save the sketch. Please copy your unsaved work into your favorite text editor, and restart the IDE.",
"offline": "Offline", "offline": "離線",
"daemonOffline": "CLI Daemon Offline", "daemonOffline": "CLI Daemon Offline",
"cannotConnectBackend": "Cannot connect to the backend.", "cannotConnectBackend": "Cannot connect to the backend.",
"cannotConnectDaemon": "Cannot connect to the CLI daemon." "cannotConnectDaemon": "Cannot connect to the CLI daemon."