(core) updates from grist-core

This commit is contained in:
Paul Fitzpatrick 2023-02-21 10:49:19 -05:00
commit cbf925aa00
29 changed files with 755 additions and 306 deletions

View File

@ -103,7 +103,6 @@ COPY --from=sandbox /runsc /usr/bin/runsc
# Add files needed for running server.
ADD package.json /grist/package.json
ADD ormconfig.js /grist/ormconfig.js
ADD bower_components /grist/bower_components
ADD sandbox /grist/sandbox
ADD plugins /grist/plugins

View File

@ -40,7 +40,6 @@ import { getOriginUrl } from 'app/common/urlUtils';
import { GristAPI, RPC_GRISTAPI_INTERFACE } from 'app/plugin/GristAPI';
import { RenderOptions, RenderTarget } from 'app/plugin/RenderOptions';
import { checkers } from 'app/plugin/TypeCheckers';
import { IpcMessageEvent } from 'electron';
import { IMsgCustom, IMsgRpcCall, Rpc } from 'grain-rpc';
import { Disposable } from './dispose';
const G = getBrowserGlobals('document', 'window');
@ -316,7 +315,7 @@ class WebviewProcess extends ViewProcess {
// TODO: find a way for keyboard events to play nice when webviews are non-modal.
Mousetrap.setPaused(true);
this.autoDisposeCallback(() => Mousetrap.setPaused(false));
webview.addEventListener('ipc-message', (event: IpcMessageEvent) => {
webview.addEventListener('ipc-message', (event: any /* IpcMessageEvent */) => {
// The event object passed to the listener is missing proper documentation. In the examples
// listed in https://electronjs.org/docs/api/ipc-main the arguments should be passed to the
// listener after the event object, but this is not happening here. Only we know it is a

View File

@ -14,7 +14,6 @@ import {GristLoadConfig} from 'app/common/gristUrls';
import {byteString, safeJsonParse} from 'app/common/gutil';
import {FetchUrlOptions, UPLOAD_URL_PATH, UploadResult} from 'app/common/uploads';
import {docUrl} from 'app/common/urlUtils';
import {OpenDialogOptions} from 'electron';
import noop = require('lodash/noop');
import trimStart = require('lodash/trimStart');
import {basename} from 'path'; // made available by webpack using path-browserify module.
@ -69,18 +68,18 @@ function getFileDialogOptions(options: SelectFileOptions): FileDialogOptions {
}
// Helper to convert SelectFileOptions to electron's OpenDialogOptions.
function getElectronOptions(options: SelectFileOptions): OpenDialogOptions {
const resOptions: OpenDialogOptions = {
filters: [],
function getElectronOptions(options: SelectFileOptions) /*: OpenDialogOptions */ {
const resOptions /*: OpenDialogOptions*/ = {
filters: [] as Array<{name: string, extensions: any}>,
properties: ['openFile'],
};
if (options.extensions) {
// Electron does not expect leading period.
const extensions = options.extensions.map(e => trimStart(e, '.'));
resOptions.filters!.push({name: 'Select files', extensions});
resOptions.filters.push({name: 'Select files', extensions});
}
if (options.multiple) {
resOptions.properties!.push('multiSelections');
resOptions.properties.push('multiSelections');
}
return resOptions;
}

View File

@ -117,6 +117,8 @@ export interface DocumentOptions {
description?: string|null;
icon?: string|null;
openMode?: OpenDocMode|null;
externalId?: string|null; // A slot for storing an externally maintained id.
// Not used in grist-core, but handy for Electron app.
}
export interface DocumentProperties extends CommonProperties {

View File

@ -120,6 +120,9 @@ export class Document extends Resource {
if (props.options.icon !== undefined) {
this.options.icon = sanitizeIcon(props.options.icon);
}
if (props.options.externalId !== undefined) {
this.options.externalId = props.options.externalId;
}
// Normalize so that null equates with absence.
for (const key of Object.keys(this.options) as Array<keyof DocumentOptions>) {
if (this.options[key] === null) {

View File

@ -36,7 +36,8 @@ import {DocWorkerInfo, IDocWorkerMap} from 'app/server/lib/DocWorkerMap';
import {expressWrap, jsonErrorHandler, secureJsonErrorHandler} from 'app/server/lib/expressWrap';
import {Hosts, RequestWithOrg} from 'app/server/lib/extractOrg';
import {addGoogleAuthEndpoint} from "app/server/lib/GoogleAuth";
import {DocTemplate, GristLoginMiddleware, GristServer, RequestWithGrist} from 'app/server/lib/GristServer';
import {DocTemplate, GristLoginMiddleware, GristLoginSystem, GristServer,
RequestWithGrist} from 'app/server/lib/GristServer';
import {initGristSessions, SessionStore} from 'app/server/lib/gristSessions';
import {HostedStorageManager} from 'app/server/lib/HostedStorageManager';
import {IBilling} from 'app/server/lib/IBilling';
@ -157,6 +158,7 @@ export class FlexServer implements GristServer {
private _getSignUpRedirectUrl: (req: express.Request, target: URL) => Promise<string>;
private _getLogoutRedirectUrl: (req: express.Request, nextUrl: URL) => Promise<string>;
private _sendAppPage: (req: express.Request, resp: express.Response, options: ISendAppPageOptions) => Promise<void>;
private _getLoginSystem?: () => Promise<GristLoginSystem>;
constructor(public port: number, public name: string = 'flexServer',
public readonly options: FlexServerOptions = {}) {
@ -233,6 +235,11 @@ export class FlexServer implements GristServer {
});
}
// Allow overridding the login system.
public setLoginSystem(loginSystem: () => Promise<GristLoginSystem>) {
this._getLoginSystem = loginSystem;
}
public getHost(): string {
return `${this.host}:${this.getOwnPort()}`;
}
@ -481,12 +488,19 @@ export class FlexServer implements GristServer {
this.app.use(/^\/help\//, expressWrap(async (req, res) => {
res.redirect('https://support.getgrist.com');
}));
// If there is a directory called "static_ext", serve material from there
// as well. This isn't used in grist-core but is handy for extensions such
// as an Electron app.
const staticExtDir = getAppPathTo(this.appRoot, 'static') + '_ext';
const staticExtApp = fse.existsSync(staticExtDir) ?
express.static(staticExtDir, options) : null;
const staticApp = express.static(getAppPathTo(this.appRoot, 'static'), options);
const bowerApp = express.static(getAppPathTo(this.appRoot, 'bower_components'), options);
if (process.env.GRIST_LOCALES_DIR) {
const locales = express.static(process.env.GRIST_LOCALES_DIR, options);
this.app.use("/locales", this.tagChecker.withTag(locales));
}
if (staticExtApp) { this.app.use(this.tagChecker.withTag(staticExtApp)); }
this.app.use(this.tagChecker.withTag(staticApp));
this.app.use(this.tagChecker.withTag(bowerApp));
}
@ -700,7 +714,7 @@ export class FlexServer implements GristServer {
this.addOrg();
// Create the sessionStore and related objects.
const {sessions, sessionMiddleware, sessionStore} = initGristSessions(this.instanceRoot, this);
const {sessions, sessionMiddleware, sessionStore} = initGristSessions(getUnpackedAppRoot(this.instanceRoot), this);
this.app.use(sessionMiddleware);
this.app.use(signInStatusMiddleware);
@ -901,11 +915,16 @@ export class FlexServer implements GristServer {
// TODO: We could include a third mock provider of login/logout URLs for better tests. Or we
// could create a mock SAML identity provider for testing this using the SAML flow.
const loginSystem = await (process.env.GRIST_TEST_LOGIN ? getTestLoginSystem() : getLoginSystem());
const loginSystem = await (process.env.GRIST_TEST_LOGIN ? getTestLoginSystem() :
(this._getLoginSystem?.() || getLoginSystem()));
this._loginMiddleware = await loginSystem.getMiddleware(this);
this._getLoginRedirectUrl = tbind(this._loginMiddleware.getLoginRedirectUrl, this._loginMiddleware);
this._getSignUpRedirectUrl = tbind(this._loginMiddleware.getSignUpRedirectUrl, this._loginMiddleware);
this._getLogoutRedirectUrl = tbind(this._loginMiddleware.getLogoutRedirectUrl, this._loginMiddleware);
const wildcardMiddleware = this._loginMiddleware.getWildcardMiddleware?.();
if (wildcardMiddleware?.length) {
this.app.use(wildcardMiddleware);
}
}
public addComm() {

View File

@ -62,6 +62,8 @@ export interface GristLoginMiddleware {
getLoginOrSignUpMiddleware?(): express.RequestHandler[];
// Optional middleware for the GET /logout route.
getLogoutMiddleware?(): express.RequestHandler[];
// Optional middleware for all routes.
getWildcardMiddleware?(): express.RequestHandler[];
// Returns arbitrary string for log.
addEndpoints(app: express.Express): Promise<string>;
// Optionally, extract profile from request. Result can be a profile,

View File

@ -35,6 +35,7 @@ export class MinIOExternalStorage implements ExternalStorage {
useSSL?: boolean,
accessKey: string,
secretKey: string,
region: string
}, private _batchSize?: number) {
this._s3 = new minio.Client(options) as MinIOClient;
}

View File

@ -40,7 +40,7 @@ export async function getMinimalLoginSystem(): Promise<GristLoginSystem> {
};
}
function getDefaultProfile(): UserProfile {
export function getDefaultProfile(): UserProfile {
return {
email: process.env.GRIST_DEFAULT_EMAIL || 'you@example.com',
name: 'You',

View File

@ -5,6 +5,7 @@ import {arrayToString} from 'app/common/arrayToString';
import * as marshal from 'app/common/marshal';
import {ISandbox, ISandboxCreationOptions, ISandboxCreator} from 'app/server/lib/ISandbox';
import log from 'app/server/lib/log';
import {getAppRoot, getAppRootFor, getUnpackedAppRoot} from 'app/server/lib/places';
import {
DirectProcessControl,
ISandboxControl,
@ -575,7 +576,7 @@ function gvisor(options: ISandboxOptions): SandboxProcess {
// Check for local virtual environments created with core's
// install:python2 or install:python3 targets. They'll need
// some extra sharing to make available in the sandbox.
const venv = path.join(process.cwd(),
const venv = path.join(getAppRootFor(getAppRoot(), 'sandbox'),
pythonVersion === '2' ? 'venv' : 'sandbox_venv3');
if (fs.existsSync(venv)) {
wrapperArgs.addMount(venv);
@ -869,19 +870,24 @@ function findPython(command: string|undefined, preferredVersion?: string) {
// TODO: rationalize this, it is a product of haphazard growth.
const prefs = preferredVersion === '2' ? ['venv', 'sandbox_venv3'] : ['sandbox_venv3', 'venv'];
for (const venv of prefs) {
const pythonPath = path.join(process.cwd(), venv, 'bin', 'python');
const base = getUnpackedAppRoot();
// Try a battery of possible python executable paths when python is installed
// in a standalone directory.
// This battery of possibilities comes from Electron packaging, where python
// is bundled with Grist. Not all the possibilities are needed (there are
// multiple popular python bundles per OS).
for (const possiblePath of [['bin', 'python'], ['bin', 'python3'],
['Scripts', 'python.exe'], ['python.exe']] as const) {
const pythonPath = path.join(base, venv, ...possiblePath);
if (fs.existsSync(pythonPath)) {
command = pythonPath;
break;
return pythonPath;
}
}
}
// Fall back on system python.
if (!command) {
command = which.sync(preferredVersion === '2' ? 'python2' : 'python3', {nothrow: true})
return which.sync(preferredVersion === '2' ? 'python2' : 'python3', {nothrow: true})
|| which.sync(preferredVersion === '2' ? 'python2.7' : 'python3.9', {nothrow: true})
|| which.sync('python');
}
return command;
}
/**

View File

@ -19,6 +19,11 @@ export function checkMinIOExternalStorage() {
preferredEnvVar: 'GRIST_DOCS_MINIO_BUCKET',
});
if (!bucket) { return undefined; }
const region = settings.flag('bucketRegion').requireString({
envVar: ['GRIST_DOCS_MINIO_BUCKET_REGION'],
preferredEnvVar: 'GRIST_DOCS_MINIO_BUCKET_REGION',
defaultValue: 'us-east-1'
});
const prefix = settings.flag('prefix').requireString({
envVar: ['GRIST_DOCS_MINIO_PREFIX'],
preferredEnvVar: 'GRIST_DOCS_MINIO_PREFIX',
@ -52,5 +57,6 @@ export function checkMinIOExternalStorage() {
useSSL,
accessKey,
secretKey,
region
};
}

View File

@ -1,6 +1,7 @@
import {synchronizeProducts} from 'app/gen-server/entity/Product';
import {codeRoot} from 'app/server/lib/places';
import {Mutex} from 'async-mutex';
import {Connection, createConnection, getConnection} from 'typeorm';
import {Connection, createConnection, DataSourceOptions, getConnection} from 'typeorm';
// Summary of migrations found in database and in code.
interface MigrationSummary {
@ -61,7 +62,7 @@ export async function getOrCreateConnection(): Promise<Connection> {
if (!String(e).match(/ConnectionNotFoundError/)) {
throw e;
}
const connection = await createConnection();
const connection = await createConnection(getTypeORMSettings());
// When using Sqlite, set a busy timeout of 3s to tolerate a little
// interference from connections made by tests. Logging doesn't show
// any particularly slow queries, but bad luck is possible.
@ -98,3 +99,49 @@ export async function undoLastMigration(connection: Connection) {
});
if (sqlite) { await connection.query("PRAGMA foreign_keys = ON;"); }
}
// Replace the old janky ormconfig.js file, which was always a source of
// pain to use since it wasn't properly integrated into the typescript
// project.
function getTypeORMSettings(): DataSourceOptions {
// If we have a redis server available, tell typeorm. Then any queries built with
// .cache() called on them will be cached via redis.
// We use a separate environment variable for the moment so that we don't have to
// enable this until we really need it.
const redisUrl = process.env.TYPEORM_REDIS_URL ? new URL(process.env.TYPEORM_REDIS_URL) : undefined;
const cache = redisUrl ? {
cache: {
type: "redis",
options: {
host: redisUrl.hostname,
port: parseInt(redisUrl.port || "6379", 10)
}
} as const
} : undefined;
return {
"name": process.env.TYPEORM_NAME || "default",
"type": (process.env.TYPEORM_TYPE as any) || "sqlite", // officially, TYPEORM_CONNECTION -
// but if we use that, this file will never
// be read, and we can't configure
// caching otherwise.
"database": process.env.TYPEORM_DATABASE || "landing.db",
"username": process.env.TYPEORM_USERNAME || undefined,
"password": process.env.TYPEORM_PASSWORD || undefined,
"host": process.env.TYPEORM_HOST || undefined,
"port": process.env.TYPEORM_PORT ? parseInt(process.env.TYPEORM_PORT, 10) : undefined,
"synchronize": false,
"migrationsRun": false,
"logging": process.env.TYPEORM_LOGGING === "true",
"entities": [
`${codeRoot}/app/gen-server/entity/*.js`
],
"migrations": [
`${codeRoot}/app/gen-server/migration/*.js` // migration files don't actually get packaged.
],
"subscribers": [
`${codeRoot}/app/gen-server/subscriber/*.js`
],
...cache,
};
}

View File

@ -9,14 +9,25 @@ import * as path from 'path';
*/
export const codeRoot = path.dirname(path.dirname(path.dirname(__dirname)));
let _cachedAppRoot: string|undefined;
/**
* Returns the appRoot, i.e. the directory containing ./sandbox, ./node_modules, ./ormconfig.js,
* Returns the appRoot, i.e. the directory containing ./sandbox, ./node_modules,
* etc.
*/
export function getAppRoot(): string {
if (_cachedAppRoot) { return _cachedAppRoot; }
_cachedAppRoot = getAppRootWithoutCaching();
return _cachedAppRoot;
}
// Uncached version of getAppRoot()
function getAppRootWithoutCaching(): string {
if (process.env.APP_ROOT_PATH) { return process.env.APP_ROOT_PATH; }
if (codeRoot.endsWith('/_build/core')) { return path.dirname(path.dirname(codeRoot)); }
return codeRoot.endsWith('/_build') ? path.dirname(codeRoot) : codeRoot;
if (codeRoot.endsWith('/_build/core') || codeRoot.endsWith('\\_build\\core')) {
return path.dirname(path.dirname(codeRoot));
}
return (codeRoot.endsWith('/_build') || codeRoot.endsWith('\\_build')) ? path.dirname(codeRoot) : codeRoot;
}
/**
@ -25,7 +36,14 @@ export function getAppRoot(): string {
* which is that .asar file in packaged form, and returns a directory where
* remaining files are available on the regular filesystem.
*/
export function getUnpackedAppRoot(appRoot: string): string {
export function getUnpackedAppRoot(appRoot: string = getAppRoot()): string {
if (path.basename(appRoot) == 'app.asar') {
return path.resolve(path.dirname(appRoot), 'app.asar.unpacked');
}
if (path.dirname(appRoot).endsWith('app.asar')) {
return path.resolve(path.dirname(path.dirname(appRoot)),
'app.asar.unpacked', 'core');
}
return path.resolve(path.dirname(appRoot), path.basename(appRoot, '.asar'));
}

View File

@ -6,6 +6,7 @@
*/
import {FlexServer, FlexServerOptions} from 'app/server/lib/FlexServer';
import {GristLoginSystem} from 'app/server/lib/GristServer';
import log from 'app/server/lib/log';
// Allowed server types. We'll start one or a combination based on the value of GRIST_SERVERS
@ -36,13 +37,14 @@ interface ServerOptions extends FlexServerOptions {
// logToConsole is set to true)
externalStorage?: boolean; // If set, documents saved to external storage such as s3 (default is to check environment
// variables, which get set in various ways in dev/test entry points)
loginSystem?: () => Promise<GristLoginSystem>;
}
/**
* Start a server on the given port, including the functionality specified in serverTypes.
*/
export async function main(port: number, serverTypes: ServerType[],
options: ServerOptions = {logToConsole: true}) {
options: ServerOptions = {}) {
const includeHome = serverTypes.includes("home");
const includeDocs = serverTypes.includes("docs");
const includeStatic = serverTypes.includes("static");
@ -50,6 +52,10 @@ export async function main(port: number, serverTypes: ServerType[],
const server = new FlexServer(port, `server(${serverTypes.join(",")})`, options);
if (options.loginSystem) {
server.setLoginSystem(options.loginSystem);
}
server.addCleanup();
server.setDirectory();
@ -58,7 +64,7 @@ export async function main(port: number, serverTypes: ServerType[],
server.testAddRouter();
}
if (options.logToConsole) { server.addLogging(); }
if (options.logToConsole !== false) { server.addLogging(); }
if (options.externalStorage === false) { server.disableExternalStorage(); }
await server.loadConfig();

View File

@ -2,10 +2,25 @@
set -e
# Use a built-in standalone version of Python if available in a directory
# called python. This is used for Electron packaging. The standalone Python
# will have extra packages installed, and then be moved to a standard location
# (sandbox_venv3).
for possible_path in python/bin/python python/bin/python3 \
python/Scripts/python.exe python/python.exe; do
if [[ -e $possible_path ]]; then
echo "found $possible_path"
buildtools/prepare_python3.sh $possible_path python
# Make sure Python2 sandbox is not around.
rm -rf venv
exit 0
fi
done
echo "Use Python3 if available and recent enough, otherwise Python2"
if python3 -c 'import sys; assert sys.version_info >= (3,9)' 2> /dev/null; then
# Default to python3 if recent enough.
buildtools/prepare_python3.sh
buildtools/prepare_python3.sh python3
# Make sure python2 isn't around.
rm -rf venv
else

View File

@ -1,12 +1,32 @@
#!/usr/bin/env bash
# Prepare a Python3 sandbox in the sandbox_venv3 directory.
# Optionally, can be called with the command to use for Python,
# and the directory of a standalone version of Python to incorporate.
set -e
echo "Making Python3 sandbox"
if [ ! -e sandbox_venv3 ]; then
python3 -m venv sandbox_venv3
if [[ -e sandbox_venv3 ]]; then
echo "Have Python3 sandbox"
exit 0
fi
python="$1"
python_dir="$2"
if [[ "$python_dir" = "" ]]; then
python=python3
pip=sandbox_venv3/bin/pip
echo "Making Python3 sandbox"
$python -m venv sandbox_venv3
else
pip="$python -m pip"
fi
echo "Updating Python3 packages"
sandbox_venv3/bin/pip install --no-deps -r sandbox/requirements3.txt
$pip install --no-deps -r sandbox/requirements3.txt
if [[ ! -e sandbox_venv3 ]]; then
echo "Moving $python_dir to sandbox_venv3"
mv $python_dir sandbox_venv3
fi
echo "Python3 packages ready in sandbox_venv3"

View File

@ -1,5 +1,10 @@
const path = require('path');
// Get path to top-level node_modules if in a yarn workspace.
// Otherwise node_modules one level up won't get resolved.
// This is used in Electron packaging.
const base = path.dirname(path.dirname(require.resolve('grainjs/package.json')));
module.exports = {
target: 'web',
entry: {
@ -18,7 +23,8 @@ module.exports = {
path.resolve('.'),
path.resolve('./ext'),
path.resolve('./stubs'),
path.resolve('./node_modules')
path.resolve('./node_modules'),
base,
],
fallback: {
'path': require.resolve("path-browserify"),

View File

@ -2,6 +2,11 @@ const MomentLocalesPlugin = require('moment-locales-webpack-plugin');
const { ProvidePlugin } = require('webpack');
const path = require('path');
// Get path to top-level node_modules if in a yarn workspace.
// Otherwise node_modules one level up won't get resolved.
// This is used in Electron packaging.
const base = path.dirname(path.dirname(require.resolve('grainjs/package.json')));
module.exports = {
target: 'web',
entry: {
@ -39,7 +44,8 @@ module.exports = {
path.resolve('.'),
path.resolve('./ext'),
path.resolve('./stubs'),
path.resolve('./node_modules')
path.resolve('./node_modules'),
base,
],
fallback: {
'path': require.resolve("path-browserify"),

View File

@ -1,49 +0,0 @@
// Cache configuration for typeorm does not seem available via ormconfig.env, so
// we use ormconfig.js style.
const {codeRoot} = require('app/server/lib/places');
module.exports = {
"name": process.env.TYPEORM_NAME || "default",
"type": process.env.TYPEORM_TYPE || "sqlite", // officially, TYPEORM_CONNECTION -
// but if we use that, this file will never
// be read, and we can't configure
// caching otherwise.
"database": process.env.TYPEORM_DATABASE || "landing.db",
"username": process.env.TYPEORM_USERNAME || null,
"password": process.env.TYPEORM_PASSWORD || null,
"host": process.env.TYPEORM_HOST || null,
"port": process.env.TYPEORM_PORT || null,
"synchronize": false,
"migrationsRun": false,
"logging": process.env.TYPEORM_LOGGING === "true",
"entities": [
`${codeRoot}/app/gen-server/entity/*.js`
],
"migrations": [
`${codeRoot}/app/gen-server/migration/*.js` // migration files don't actually get packaged.
],
"subscribers": [
`${codeRoot}/app/gen-server/subscriber/*.js`
],
"cli": {
"entitiesDir": `${codeRoot}/app/gen-server/entity`,
"migrationsDir": `${codeRoot}/app/gen-server/migration`,
"subscribersDir": `${codeRoot}/app/gen-server/subscriber`
}
};
// If we have a redis server available, tell typeorm. Then any queries built with
// .cache() called on them will be cached via redis.
// We use a separate environment variable for the moment so that we don't have to
// enable this until we really need it.
if (process.env.TYPEORM_REDIS_URL) {
const url = require('url').parse(process.env.TYPEORM_REDIS_URL);
module.exports.cache = {
type: "redis",
options: {
host: url.hostname,
port: parseInt(url.port || "6379", 10)
}
};
}

View File

@ -131,7 +131,6 @@
"csv": "4.0.0",
"diff-match-patch": "1.0.5",
"double-ended-queue": "2.1.0-0",
"electron": "19.0.9",
"exceljs": "4.2.1",
"express": "4.16.4",
"file-type": "16.5.4",

View File

@ -434,7 +434,8 @@
"Welcome to Grist, {{name}}!": "Willkommen bei Grist, {{name}}!",
"Welcome to {{orgName}}": "Willkommen bei {{orgName}}",
"You have read-only access to this site. Currently there are no documents.": "Sie haben nur Lesezugriff auf diese Seite. Derzeit sind keine Dokumente vorhanden.",
"personal site": "persönliche Seite"
"personal site": "persönliche Seite",
"{{signUp}} to save your work. ": "{{signUp}} um Ihre Arbeit zu speichern. "
},
"HomeLeftPane": {
"Access Details": "Zugangsdetails",
@ -963,5 +964,45 @@
},
"LanguageMenu": {
"Language": "Sprache"
},
"GristTooltips": {
"Learn more.": "Mehr erfahren.",
"Editing Card Layout": "Kartenlayout bearbeiten",
"Cells in a reference column always identify an {{entire}} record in that table, but you may select which column from that record to show.": "Zellen in einer Referenzspalte identifizieren immer einen {{entire}} Datensatz in dieser Tabelle, aber Sie können auswählen, welche Spalte aus diesem Datensatz angezeigt werden soll.",
"Apply conditional formatting to cells in this column when formula conditions are met.": "Wenden Sie bedingte Formatierung auf Zellen in dieser Spalte an, wenn Formelbedingungen erfüllt sind.",
"Apply conditional formatting to rows based on formulas.": "Wenden Sie bedingte Formatierung auf Zeilen basierend auf Formeln an.",
"Click on “Open row styles” to apply conditional formatting to rows.": "Klicken Sie auf „Zeilenstile öffnen“, um eine bedingte Formatierung auf Zeilen anzuwenden.",
"Click the Add New button to create new documents or workspaces, or import data.": "Klicken Sie auf die Schaltfläche Neu hinzufügen, um neue Dokumente oder Arbeitsbereiche zu erstellen oder Daten zu importieren.",
"Clicking {{EyeHideIcon}} in each cell hides the field from this view without deleting it.": "Wenn Sie in jeder Zelle auf {{EyeHideIcon}} klicken, wird das Feld aus dieser Ansicht ausgeblendet, ohne es zu löschen.",
"Formulas that trigger in certain cases, and store the calculated value as data.": "Formeln, die in bestimmten Fällen auslösen und den berechneten Wert als Daten speichern.",
"Link your new widget to an existing widget on this page.": "Verknüpfen Sie Ihr neues Widget mit einem bestehenden Widget auf dieser Seite.",
"Linking Widgets": "Widgets verknüpfen",
"Nested Filtering": "Verschachtelte Filterung",
"Pinning Filters": "Anheften von Filtern",
"Raw Data page": "Rohdatenseite",
"Select the table to link to.": "Wählen Sie die zu verknüpfende Tabelle aus.",
"Selecting Data": "Daten auswählen",
"The total size of all data in this document, excluding attachments.": "Die Gesamtgröße aller Daten in diesem Dokument, ohne Anhänge.",
"Updates every 5 minutes.": "Aktualisiert alle 5 Minuten.",
"relational": "relationale",
"Unpin to hide the the button while keeping the filter.": "Lösen Sie die Anheftung, um die Schaltfläche auszublenden und den Filter beizubehalten.",
"Only those rows will appear which match all of the filters.": "Es werden nur die Zeilen angezeigt, die allen Filtern entsprechen.",
"Pinned filters are displayed as buttons above the widget.": "Angeheftete Filter werden als Schaltflächen über dem Widget angezeigt.",
"Rearrange the fields in your card by dragging and resizing cells.": "Ordnen Sie die Felder in Ihrer Karte neu an, indem Sie die Zellen ziehen und ihre Größe ändern.",
"Reference Columns": "Referenzspalten",
"Reference columns are the key to {{relational}} data in Grist.": "Referenzspalten sind der Schlüssel zu {{relational}} Daten in Grist.",
"Select the table containing the data to show.": "Wählen Sie die Tabelle mit den anzuzeigenden Daten aus.",
"Add New": "Neu hinzufügen",
"Use the \\u{1D6BA} icon to create summary (or pivot) tables, for totals or subtotals.": "Verwenden Sie das Symbol \\u{1D6BA}, um zusammenfassende (oder Pivot-)Tabellen für Summen oder Zwischensummen zu erstellen.",
"Use the 𝚺 icon to create summary (or pivot) tables, for totals or subtotals.": "Verwenden Sie das Symbol 𝚺, um zusammenfassende (oder Pivot-)Tabellen für Summen oder Zwischensummen zu erstellen.",
"The Raw Data page lists all data tables in your document, including summary tables and tables not included in page layouts.": "Auf der Rohdatenseite werden alle Datentabellen in Ihrem Dokument aufgelistet, einschließlich Zusammenfassungstabellen und Tabellen, die nicht in Seitenlayouts enthalten sind.",
"Useful for storing the timestamp or author of a new record, data cleaning, and more.": "Nützlich zum Speichern des Zeitstempels oder Autors eines neuen Datensatzes, zur Datenbereinigung und mehr.",
"They allow for one record to point (or refer) to another.": "Sie ermöglichen es, dass ein Datensatz auf einen anderen zeigt (oder verweist).",
"This is the secret to Grist's dynamic and productive layouts.": "Dies ist das Geheimnis für Grists dynamische und produktive Layouts.",
"Try out changes in a copy, then decide whether to replace the original with your edits.": "Probieren Sie Änderungen in einer Kopie aus, dann entscheiden Sie, ob Sie das Original durch Ihre Bearbeitungen ersetzen.",
"You can filter by more than one column.": "Sie können nach mehr als einer Spalte filtern.",
"entire": "gesamte",
"Access Rules": "Zugriffsregeln",
"Access rules give you the power to create nuanced rules to determine who can see or edit which parts of your document.": "Zugriffsregeln geben Ihnen die Möglichkeit, nuancierte Regeln zu erstellen, um festzulegen, wer welche Teile Ihres Dokuments sehen oder bearbeiten kann."
}
}

View File

@ -929,7 +929,7 @@
"They allow for one record to point (or refer) to another.": "They allow for one record to point (or refer) to another.",
"This is the secret to Grist's dynamic and productive layouts.": "This is the secret to Grist's dynamic and productive layouts.",
"Try out changes in a copy, then decide whether to replace the original with your edits.": "Try out changes in a copy, then decide whether to replace the original with your edits.",
"Unpin to hide the the button while keeping the filter.": "Unpin to hide the the button while keeping the filter.",
"Unpin to hide the the button while keeping the filter.": "Unpin to hide the button while keeping the filter.",
"Updates every 5 minutes.": "Updates every 5 minutes.",
"Use the \\u{1D6BA} icon to create summary (or pivot) tables, for totals or subtotals.": "Use the \\u{1D6BA} icon to create summary (or pivot) tables, for totals or subtotals.",
"Useful for storing the timestamp or author of a new record, data cleaning, and more.": "Useful for storing the timestamp or author of a new record, data cleaning, and more.",
@ -937,6 +937,8 @@
"entire": "entire",
"relational": "relational",
"Access Rules": "Access Rules",
"Access rules give you the power to create nuanced rules to determine who can see or edit which parts of your document.": "Access rules give you the power to create nuanced rules to determine who can see or edit which parts of your document."
"Access rules give you the power to create nuanced rules to determine who can see or edit which parts of your document.": "Access rules give you the power to create nuanced rules to determine who can see or edit which parts of your document.",
"Add New": "Add New",
"Use the 𝚺 icon to create summary (or pivot) tables, for totals or subtotals.": "Use the 𝚺 icon to create summary (or pivot) tables, for totals or subtotals."
}
}

View File

@ -358,7 +358,8 @@
"Welcome to Grist, {{name}}!": "¡Bienvenido a Grist, {{name}}!",
"Welcome to {{orgName}}": "Bienvenido a {{orgName}}",
"You have read-only access to this site. Currently there are no documents.": "Tiene acceso sólo lectura a este sitio. Actualmente no hay documentos.",
"personal site": "sitio personal"
"personal site": "sitio personal",
"{{signUp}} to save your work. ": "{{signUp}} para guardar tu trabajo. "
},
"HomeLeftPane": {
"Access Details": "Detalles de Acceso",
@ -953,5 +954,45 @@
},
"LanguageMenu": {
"Language": "Idioma"
},
"GristTooltips": {
"Apply conditional formatting to cells in this column when formula conditions are met.": "Aplicar formato condicional a las células en esta columna cuando se cumplen las condiciones de la fórmula.",
"Clicking {{EyeHideIcon}} in each cell hides the field from this view without deleting it.": "Al hacer clic en {{EyeHideIcon}} en cada celda esconde el campo desde esta vista sin borrarlo.",
"Pinned filters are displayed as buttons above the widget.": "Los filtros anclados se muestran como botones encima del widget.",
"Pinning Filters": "Anclando filtros",
"Raw Data page": "Página de datos brutos",
"Reference Columns": "Columnas de referencia",
"Apply conditional formatting to rows based on formulas.": "Aplicar formato condicional a filas basado en fórmulas.",
"Click on “Open row styles” to apply conditional formatting to rows.": "Haga clic en \"Abrir estilos de filas\" para aplicar formato condicional a filas.",
"Click the Add New button to create new documents or workspaces, or import data.": "Haga clic en el botón Añadir nuevo para crear nuevos documentos o espacios de trabajo, o importar datos.",
"Editing Card Layout": "Editando diseño de la tarjeta",
"Cells in a reference column always identify an {{entire}} record in that table, but you may select which column from that record to show.": "Las celdas en una columna de referencia siempre identifican un registro {{entire}} en esa tabla, pero puede seleccionar qué columna de ese registro mostrar.",
"Formulas that trigger in certain cases, and store the calculated value as data.": "Fórmulas que se activan en ciertos casos y almacenan el valor calculado como datos.",
"Link your new widget to an existing widget on this page.": "Vincule su nuevo widget a un widget existente en esta página.",
"Linking Widgets": "Vinculando widgets",
"Learn more.": "Más información.",
"Only those rows will appear which match all of the filters.": "Sólo aparecerán las filas que coincidan con todos los filtros.",
"Nested Filtering": "Filtros anidados",
"Rearrange the fields in your card by dragging and resizing cells.": "Reorganice los campos de su tarjeta arrastrando y cambiando el tamaño de las celdas.",
"Reference columns are the key to {{relational}} data in Grist.": "Las columnas de referencia son la clave de los datos {{relational}} en Grist.",
"Selecting Data": "Seleccionando datos",
"Try out changes in a copy, then decide whether to replace the original with your edits.": "Prueba los cambios en una copia y, a continuación, decide si quieres reemplazar el original con tus ediciones.",
"Use the \\u{1D6BA} icon to create summary (or pivot) tables, for totals or subtotals.": "Utilice el icono \\u{1D6BA} para crear tablas resumen (o dinámicas), para totales o subtotales.",
"Useful for storing the timestamp or author of a new record, data cleaning, and more.": "Útil para almacenar la marca de tiempo o el autor de un nuevo registro, limpieza de datos y más.",
"Access rules give you the power to create nuanced rules to determine who can see or edit which parts of your document.": "Las reglas de acceso le dan el poder de crear reglas matizadas para determinar quién puede ver o editar qué partes de su documento.",
"Select the table containing the data to show.": "Seleccione la tabla que contiene los datos que desea mostrar.",
"Select the table to link to.": "Seleccione la tabla a vincular.",
"The total size of all data in this document, excluding attachments.": "El tamaño total de todos los datos en este documento, excluyendo los adjuntos.",
"They allow for one record to point (or refer) to another.": "Permiten que un registro apunte (o se refiera) a otro.",
"The Raw Data page lists all data tables in your document, including summary tables and tables not included in page layouts.": "La página Datos brutos enumera todas las tablas de datos del documento, incluidas las tablas de resumen y las tablas no incluidas en los diseños de página.",
"This is the secret to Grist's dynamic and productive layouts.": "Este es el secreto de los diseños dinámicos y productivos de Grist.",
"Updates every 5 minutes.": "Actualiza cada 5 minutos.",
"You can filter by more than one column.": "Puedes filtrar por más de una columna.",
"Add New": "Agregar Nuevo",
"entire": "entero",
"relational": "relacionales",
"Access Rules": "Reglas de acceso",
"Use the 𝚺 icon to create summary (or pivot) tables, for totals or subtotals.": "Utilice el icono 𝚺 para crear tablas resumen (o dinámicas), para totales o subtotales.",
"Unpin to hide the the button while keeping the filter.": "Desancla para ocultar el botón mientras mantienes el filtro."
}
}

View File

@ -18,7 +18,8 @@
"Welcome to Grist!": "Benvenuto in Grist!",
"Welcome to Grist, {{name}}!": "Benvenuto in Grist, {{name}}!",
"Welcome to {{orgName}}": "Benvenuto in {{orgName}}",
"You have read-only access to this site. Currently there are no documents.": "Hai accesso a questo sito in sola lettura. Attualmente non ci sono documenti."
"You have read-only access to this site. Currently there are no documents.": "Hai accesso a questo sito in sola lettura. Attualmente non ci sono documenti.",
"{{signUp}} to save your work. ": "{{signUp}} per salvare il tuo lavoro. "
},
"HomeLeftPane": {
"Manage Users": "Gestisci gli utenti",
@ -899,5 +900,45 @@
"CodeEditorPanel": {
"Code View is available only when you have full document access.": "Vista Codice è disponibile solo quando hai pieno accesso al documento.",
"Access denied": "Accesso negato"
},
"GristTooltips": {
"Click on “Open row styles” to apply conditional formatting to rows.": "Clicca su \"Apri stile righe\" per applicare la formattazione condizionale alle righe.",
"Editing Card Layout": "Modifica Layout Scheda",
"Apply conditional formatting to cells in this column when formula conditions are met.": "Applica la formattazione condizionale alle celle in questa colonna quando le condizioni della formula sono soddisfatte.",
"Apply conditional formatting to rows based on formulas.": "Applica la formattazione condizionale alle righe in base alle formule.",
"Clicking {{EyeHideIcon}} in each cell hides the field from this view without deleting it.": "Cliccando {{EyeHideIcon}} si nasconde il campo dalla vista senza cancellarlo.",
"Click the Add New button to create new documents or workspaces, or import data.": "Clicca il bottone Aggiungi Nuovo per creare nuovi documenti, workspace, o importare dei dati.",
"Formulas that trigger in certain cases, and store the calculated value as data.": "Formule che si attivano in certi casi, e conservano il valore calcolato come dato.",
"Linking Widgets": "Collegare i widget",
"Nested Filtering": "Filtri innestati",
"Only those rows will appear which match all of the filters.": "Saranno mostrate solo le righe che soddisfano tutte le condizioni filtro.",
"Pinning Filters": "Fissare i filtri",
"Reference Columns": "Colonne con riferimenti",
"Select the table containing the data to show.": "Seleziona la tabella che contiene i dati da mostrare.",
"Selecting Data": "Selezionare i dati",
"This is the secret to Grist's dynamic and productive layouts.": "Questo è il segreto dei layout dinamici e produttivi di Grist.",
"Try out changes in a copy, then decide whether to replace the original with your edits.": "Prova i cambiamenti in una copia, quindi decidi se rimpiazzare l'originale con le tue modifiche.",
"Updates every 5 minutes.": "Si aggiorna ogni 5 minuti.",
"Useful for storing the timestamp or author of a new record, data cleaning, and more.": "Utile per conservare data e ora, o l'autore di un nuovo record, per la pulizia dei dati e altro ancora.",
"Use the \\u{1D6BA} icon to create summary (or pivot) tables, for totals or subtotals.": "Usa il simbolo \\u{1D6BA} per creare tabelle riassuntive (pivot), per totali e subtotali.",
"Add New": "Aggiungi nuovo",
"Unpin to hide the the button while keeping the filter.": "Sblocca per nascondere il pulsante, mantenendo comunque il filtro.",
"Select the table to link to.": "Seleziona la tabella da collegare.",
"Cells in a reference column always identify an {{entire}} record in that table, but you may select which column from that record to show.": "Le celle in una colonna referenziata indentificano sempre un record {{entire}} di una tabella, ma puoi scegliere quale colonna mostrare da quel record.",
"Learn more.": "Scopri di più.",
"Link your new widget to an existing widget on this page.": "Collega il tuo widget a un widget già esistente in questa pagina.",
"Rearrange the fields in your card by dragging and resizing cells.": "Sposta e ridimensiona le celle per riconfigurare i campi nella tua scheda.",
"You can filter by more than one column.": "Puoi filtrare secondo più di una colonna.",
"Pinned filters are displayed as buttons above the widget.": "I filtri fissati sono mostrati come pulsanti sopra il widget.",
"Raw Data page": "Pagine di dati grezzi",
"The total size of all data in this document, excluding attachments.": "Lo spazio totale di tutti i dati in questo documento, esclusi gli allegati.",
"The Raw Data page lists all data tables in your document, including summary tables and tables not included in page layouts.": "La pagina dei dati grezzi elenca tutte le tabelle-dati nel tuo documento, incluse le tabelle sommario e le tabelle non comprese nei layout delle pagine.",
"They allow for one record to point (or refer) to another.": "Permettono a un record di puntare (o riferirsi) a un altro.",
"entire": "intero",
"relational": "relazionale",
"Use the 𝚺 icon to create summary (or pivot) tables, for totals or subtotals.": "Usa il simbolo 𝚺 per creare tabelle riassuntive (pivot), per totali o subtotali.",
"Access Rules": "Regole di accesso",
"Access rules give you the power to create nuanced rules to determine who can see or edit which parts of your document.": "Le regole di accesso ti danno il potere di creare regole sofisticate per decidere chi può vedere o modificare il tuo documento, e quali parti.",
"Reference columns are the key to {{relational}} data in Grist.": "Le colonne con riferimenti sono il motore {{relational}} dei dati in Grist."
}
}

View File

@ -9,37 +9,37 @@
"Add Default Rule": "Dodaj domyślną regułę",
"Add Table Rules": "Dodaj reguły tabeli",
"Add User Attributes": "Dodawanie atrybutów użytkownika",
"Allow everyone to copy the entire document, or view it in full in fiddle mode.\nUseful for examples and templates, but not for sensitive data.": "Pozwól każdemu skopiować cały dokument lub obejrzeć go w całości w trybie skrzypiec. Przydatne dla przykładów i szablonów, ale nie dla wrażliwych danych.",
"Allow everyone to copy the entire document, or view it in full in fiddle mode.\nUseful for examples and templates, but not for sensitive data.": "Pozwól innym skopiować lub obejrzeć cały dokument w trybie roboczym.\nOpcja przydatna dla przykładów i szablonów, ale nie powinna być używana dla wrażliwych danych.",
"Allow everyone to view Access Rules.": "Zezwalaj wszystkim na wyświetlanie reguł dostępu.",
"Attribute name": "Nazwa atrybutu",
"Attribute to Look Up": "Atrybut do wyszukania",
"Checking...": "Sprawdzanie…",
"Condition": "Stan",
"Default Rules": "Zasady domyślne",
"Condition": "Reguła",
"Default Rules": "Reguły domyślne",
"Delete Table Rules": "Usuń reguły tabeli",
"Enter Condition": "Wprowadź warunek",
"Enter Condition": "Wprowadź regułę",
"Everyone": "Wszyscy",
"Everyone Else": "Wszyscy inni",
"Everyone Else": "Pozostali",
"Invalid": "Nieprawidłowy",
"Lookup Column": "Kolumna wyszukiwania",
"Lookup Table": "Tablica poglądowa",
"Lookup Table": "Tabela",
"Permission to access the document in full when needed": "Pozwolenie na pełny dostęp do dokumentu w razie potrzeby",
"Permission to view Access Rules": "Uprawnienia do przeglądania reguł dostępu",
"Permissions": "Uprawnienia",
"Remove column {{- colId }} from {{- tableId }} rules": "Usuń kolumnę {{- colId }} z reguł {{- tableId }}",
"Remove {{- tableId }} rules": "Usuń zasady {{- tableId }}",
"Remove {{- tableId }} rules": "Usuń reguły {{- tableId }}",
"Remove {{- name }} user attribute": "Usuń atrybut użytkownika {{- name }}",
"Reset": "Reset",
"Rules for table ": "Zasady dotyczące tabeli ",
"Save": "Zapisz",
"Saved": "Zapisano",
"Special Rules": "Zasady specjalne",
"Special Rules": "Reguły specjalne",
"Type a message...": "Wpisz wiadomość…",
"User Attributes": "Atrybuty użytkownika",
"View As": "Wyświetl jako",
"Seed rules": "Zasady seedowania",
"When adding table rules, automatically add a rule to grant OWNER full access.": "Podczas dodawania reguł tabeli automatycznie dodaj regułę, aby przyznać WŁAŚCICIELOWI pełny dostęp.",
"Permission to edit document structure": "Pozwolenie na edycję struktury dokumentu"
"Seed rules": "Zasady bazowe",
"When adding table rules, automatically add a rule to grant OWNER full access.": "Automatycznie dodawaj regułę przyznającą właścicielowi pełen dostęp.",
"Permission to edit document structure": "Uprawnienie do edycji struktury dokumentu"
},
"AccountPage": {
"API": "API",
@ -56,7 +56,7 @@
"Save": "Zapisz",
"Theme": "Motyw",
"Two-factor authentication": "Uwierzytelnianie dwuskładnikowe",
"Two-factor authentication is an extra layer of security for your Grist account designed to ensure that you're the only person who can access your account, even if someone knows your password.": "Uwierzytelnianie dwuskładnikowe to dodatkowa warstwa zabezpieczeń konta Grist, która zapewnia, że jesteś jedyną osobą, która ma dostęp do konta, nawet jeśli ktoś zna Twoje hasło.",
"Two-factor authentication is an extra layer of security for your Grist account designed to ensure that you're the only person who can access your account, even if someone knows your password.": "Uwierzytelnianie dwuetapowe to dodatkowa warstwa zabezpieczeń konta Grist, która zapewnia, że jesteś jedyną osobą, która ma dostęp do konta, nawet jeśli ktoś zna Twoje hasło.",
"Language": "Język"
},
"AccountWidget": {
@ -68,7 +68,7 @@
"Pricing": "Cennik",
"Profile Settings": "Ustawienia profilu",
"Sign Out": "Wyloguj się",
"Sign in": "Rejestrowanie",
"Sign in": "Zaloguj się",
"Switch Accounts": "Przełącz konta",
"Toggle Mobile Mode": "Przełącz na tryb mobilny"
},
@ -112,27 +112,27 @@
},
"CellContextMenu": {
"Clear cell": "Wyczyść komórkę",
"Copy anchor link": "Kopiowanie łącza zakotwiczenia",
"Copy anchor link": "Kopiuj link",
"Delete {{count}} columns_one": "Usuń kolumnę",
"Delete {{count}} columns_other": "Usuń kolumny {{count}}",
"Delete {{count}} rows_one": "Usunąć wiersz",
"Delete {{count}} rows_other": "Usuwanie wierszy {{count}}",
"Delete {{count}} columns_other": "Usuń {{count}} kolumny",
"Delete {{count}} rows_one": "Usuń wiersz",
"Delete {{count}} rows_other": "Usuń {{count}} wierszy",
"Duplicate rows_one": "Duplikuj wiersz",
"Duplicate rows_other": "Duplikuj wiersze",
"Filter by this value": "Filtruj według tej wartości",
"Insert column to the left": "Wstaw kolumnę z lewej strony",
"Insert column to the right": "Wstaw kolumnę z prawej strony",
"Insert row above": "Wstaw wiersz powyżej",
"Reset {{count}} columns_one": "Wyzerować kolumnę",
"Reset {{count}} columns_other": "Resetowanie kolumn {{count}}",
"Reset {{count}} entire columns_one": "Wyzeruj całą kolumnę",
"Reset {{count}} entire columns_other": "Resetuj {{count}} całe kolumny",
"Insert row above": "Wstaw wiersz powyżej",
"Reset {{count}} columns_one": "Zresetuj kolumnę",
"Reset {{count}} columns_other": "Zresetuj {{count}} kolumn",
"Reset {{count}} entire columns_one": "Zresetuj całą kolumnę",
"Reset {{count}} entire columns_other": "Zresetuj {{count}} kolumn",
"Clear values": "Wyczyść wartości",
"Insert row below": "Wstaw wiersz poniżej",
"Insert row": "Wstaw wiersz"
"Insert row below": "Wstaw wiersz poniżej",
"Insert row": "Wstaw wiersz"
},
"ChartView": {
"Create separate series for each value of the selected column.": "Tworzenie osobnych serii dla każdej wartości wybranej kolumny.",
"Create separate series for each value of the selected column.": "Utwórz osobne serie dla każdej wartości z wybranej kolumny.",
"Each Y series is followed by two series, for top and bottom error bars.": "Po każdej serii Y następują dwie serie, dla górnych i dolnych słupków błędów.",
"Pick a column": "Wybierz kolumnę",
"Toggle chart aggregation": "Przełączanie agregacji wykresów",
@ -223,11 +223,36 @@
"Deleted {{at}}": "Usunięto {{at}}",
"Discover More Templates": "Odkryj więcej szablonów",
"Documents stay in Trash for 30 days, after which they get deleted permanently.": "Dokumenty pozostają w Koszu przez 30 dni, po czym zostają trwale usunięte.",
"Document will be permanently deleted.": "Dokument zostanie na stałe usunięty."
"Document will be permanently deleted.": "Dokument zostanie na stałe usunięty.",
"Unpin Document": "Odepnij Dokument",
"Remove": "Usuń",
"Rename": "Zmień nazwę",
"Requires edit permissions": "Wymagane uprawnienia do edycji",
"Restore": "Przywróć",
"To restore this document, restore the workspace first.": "Aby przywrócić ten dokument, najpierw przywróć obszar roboczy.",
"Trash": "Kosz",
"Trash is empty.": "Kosz jest pusty.",
"Workspace not found": "Nie odnaleziono obszaru roboczego",
"You are on your personal site. You also have access to the following sites:": "Jesteś w swojej osobistej przestrzeni. Masz dostęp także do:",
"You may delete a workspace forever once it has no documents in it.": "Ponieważ ten obszar roboczy nie zawiera żadnych dokumentów, możesz skasować go na stałe.",
"This service is not available right now": "Usługa jest aktualnie niedostępna",
"You are on the {{siteName}} site. You also have access to the following sites:": "Jesteś w przestrzeni {{siteName}}. Oprócz niej, masz dostęp także do:"
},
"ColorSelect": {
"Apply": "Zastosuj",
"Cancel": "Anuluj",
"Default cell style": "Domyślny styl komórki"
},
"DocPageModel": {
"Add Empty Table": "Dodaj pustą tabele",
"Add Page": "Dodaj stronę",
"Add Widget to Page": "Dodaj widżet do strony",
"Document owners can attempt to recover the document. [{{error}}]": "Właściciel dokumentu może podjąć próbę odzyskania go. {{error}}",
"Enter recovery mode": "Przejdź w tryb odzyskiwania",
"Error accessing document": "Błąd w trakcie pobierania dokumentu",
"Reload": "Przeładuj",
"Sorry, access to this document has been denied. [{{error}}]": "Przepraszamy ale nie masz dostępu do tego dokumentu. [{{error}}]",
"You do not have edit access to this document": "nie masz uprawnień do edytowania tego dokumentu",
"You can try reloading the document, or using recovery mode. Recovery mode opens the document to be fully accessible to owners, and inaccessible to others. It also disables formulas. [{{error}}]": "Spróbuj przeładować dokument, albo użyj trybu odzyskiwania. W trybie odzyskiwania dokument jest otwarty z pełnym dostępem dla właściciela i jako niedostępny dla kogokolwiek innego, a formuły są wyłączone. [{{error}}]"
}
}

View File

@ -434,7 +434,8 @@
"Welcome to Grist, {{name}}!": "Bem-vindo ao Grist, {{name}}!",
"Welcome to {{orgName}}": "Bem-vindo ao {{orgName}}",
"You have read-only access to this site. Currently there are no documents.": "Você só tem acesso de leitura a este site. Atualmente não há documentos.",
"personal site": "Site pessoal"
"personal site": "Site pessoal",
"{{signUp}} to save your work. ": "{{signUp}} para salvar seu trabalho. "
},
"HomeLeftPane": {
"Access Details": "Detalhes de Acesso",
@ -963,5 +964,45 @@
},
"LanguageMenu": {
"Language": "Idioma"
},
"GristTooltips": {
"Cells in a reference column always identify an {{entire}} record in that table, but you may select which column from that record to show.": "As células em uma coluna de referência sempre identificam um registro {{entire}} nessa tabela, mas você pode selecionar qual coluna desse registro deve ser mostrada.",
"Formulas that trigger in certain cases, and store the calculated value as data.": "Fórmulas que acionam em certos casos, e armazenam o valor calculado como dados.",
"Link your new widget to an existing widget on this page.": "Vincule seu novo widget a um widget existente nesta página.",
"Linking Widgets": "Vinculando widgets",
"Nested Filtering": "Filtragem aninhada",
"Only those rows will appear which match all of the filters.": "Somente serão exibidas as linhas que correspondem a todos os filtros.",
"Reference Columns": "Colunas de referência",
"Select the table to link to.": "Selecione a tabela à qual se vincular.",
"Selecting Data": "Selecionando dados",
"The total size of all data in this document, excluding attachments.": "O tamanho total de todos os dados deste documento, excluindo os anexos.",
"Updates every 5 minutes.": "Atualiza a cada 5 minutos.",
"You can filter by more than one column.": "Você pode filtrar por mais de uma coluna.",
"Access Rules": "Regras de Acesso",
"Add New": "Adicionar Novo",
"Click the Add New button to create new documents or workspaces, or import data.": "Clique no botão Adicionar Novo para criar novos documentos ou espaços de trabalho ou importar dados.",
"Apply conditional formatting to cells in this column when formula conditions are met.": "Aplicar formatação condicional às células nesta coluna quando as condições da fórmula forem atendidas.",
"Apply conditional formatting to rows based on formulas.": "Aplicar formatação condicional em linhas com base em fórmulas.",
"Click on “Open row styles” to apply conditional formatting to rows.": "Clique em \"Abrir estilos de linhas\" para aplicar a formatação condicional às linhas.",
"Clicking {{EyeHideIcon}} in each cell hides the field from this view without deleting it.": "Clicar {{EyeHideIcon}} em cada célula esconde o campo desta visualização sem apagá-lo.",
"Editing Card Layout": "Editando o layout do cartão",
"Learn more.": "Saiba mais.",
"Raw Data page": "Página de dados brutos",
"Reference columns are the key to {{relational}} data in Grist.": "As colunas de referência são a chave para os dados {{relational}} no Grist.",
"Pinning Filters": "Fixando filtros",
"Rearrange the fields in your card by dragging and resizing cells.": "Organize os campos em seu cartão arrastando e redimensionando células.",
"Pinned filters are displayed as buttons above the widget.": "Os filtros fixados são exibidos como botões acima do widget.",
"Select the table containing the data to show.": "Selecione a tabela que contém os dados a serem exibidos.",
"They allow for one record to point (or refer) to another.": "Eles permitem que um registro aponte (ou se refira) a outro.",
"The Raw Data page lists all data tables in your document, including summary tables and tables not included in page layouts.": "A página de dados brutos lista todas as tabelas de dados em seu documento, incluindo tabelas de resumo e tabelas não incluídas nos layouts de página.",
"This is the secret to Grist's dynamic and productive layouts.": "Este é o segredo dos layouts dinâmicos e produtivos do Grist.",
"Try out changes in a copy, then decide whether to replace the original with your edits.": "Experimente mudanças em uma cópia, depois decida se deseja substituir o original por suas edições.",
"Use the \\u{1D6BA} icon to create summary (or pivot) tables, for totals or subtotals.": "Use o ícone \\u{1D6BA} para criar tabelas de resumo (ou dinâmicas) para totais ou subtotais.",
"Useful for storing the timestamp or author of a new record, data cleaning, and more.": "Útil para armazenar o carimbo da hora ou autor de um novo registro, limpeza de dados, e muito mais.",
"entire": "inteiro",
"Access rules give you the power to create nuanced rules to determine who can see or edit which parts of your document.": "As regras de acesso lhe dão o poder de criar regras diferenciadas para determinar quem pode ver ou editar quais partes de seu documento.",
"Use the 𝚺 icon to create summary (or pivot) tables, for totals or subtotals.": "Use o ícone 𝚺 para criar tabelas resumidas (ou dinâmicas), para totais ou subtotais.",
"relational": "relacionais",
"Unpin to hide the the button while keeping the filter.": "Desfixe para ocultar o botão enquanto mantém o filtro."
}
}

View File

@ -436,7 +436,7 @@
"Grid Options": "Параметры сетки",
"Vertical Gridlines": "Вертикальные линии сетки",
"Horizontal Gridlines": "Горизонтальные линии сетки",
"Zebra Stripes": "Полосы зебры"
"Zebra Stripes": "Чересстрочная заливка"
},
"HomeIntro": {
"Interested in using Grist outside of your team? Visit your free ": "Заинтересованы в использовании Grist вне вашей команды? Попробуйте бесплатно ",
@ -457,7 +457,8 @@
"Welcome to Grist!": "Добро пожаловать в Grist!",
"Welcome to {{orgName}}": "Добро пожаловать в {{orgName}}",
"personal site": "личный сайт",
"You have read-only access to this site. Currently there are no documents.": "Вы имеете доступ к этому сайту только для просмотра. В настоящее время документов нет."
"You have read-only access to this site. Currently there are no documents.": "Вы имеете доступ к этому сайту только для просмотра. В настоящее время документов нет.",
"{{signUp}} to save your work. ": "{{signUp}} сохранить свою работу. "
},
"HomeLeftPane": {
"Import Document": "Импорт документа",
@ -899,5 +900,45 @@
},
"HyperLinkEditor": {
"[link label] url": "[link label] url"
},
"GristTooltips": {
"Clicking {{EyeHideIcon}} in each cell hides the field from this view without deleting it.": "Нажатие {{EyeHideIcon}} в каждой ячейке скрывает поле из этого представления, не удаляя его.",
"Formulas that trigger in certain cases, and store the calculated value as data.": "Формулы, которые срабатывают в определенных случаях и сохраняют вычисленное значение в виде данных.",
"Learn more.": "Узнать больше.",
"Linking Widgets": "Связывание виджетов",
"Nested Filtering": "Вложенная фильтрация",
"Editing Card Layout": "Редактирование макета карточки",
"Pinned filters are displayed as buttons above the widget.": "Закрепленные фильтры отображаются в виде кнопок над виджетом.",
"Pinning Filters": "Закрепление фильтров",
"Raw Data page": "Страница необработанных данных",
"Reference Columns": "Ссылочные столбцы",
"Select the table containing the data to show.": "Выберите таблицу, содержащую данные для отображения.",
"Select the table to link to.": "Выберите таблицу для ссылки.",
"Selecting Data": "Выбор данных",
"The total size of all data in this document, excluding attachments.": "Общий размер всех данных в этом документе, за исключением вложений.",
"They allow for one record to point (or refer) to another.": "Они позволяют одной записи указывать (или ссылаться) на другую.",
"This is the secret to Grist's dynamic and productive layouts.": "В этом секрет динамичных и продуктивных макетов Grist.",
"Updates every 5 minutes.": "Обновляется каждые 5 минут.",
"Use the \\u{1D6BA} icon to create summary (or pivot) tables, for totals or subtotals.": "Используйте \\u{1D6BA} значок для создания сводных таблиц для итогов или промежуточных итогов.",
"You can filter by more than one column.": "Вы можете выполнить фильтрацию более чем по одному столбцу.",
"entire": "весь",
"Only those rows will appear which match all of the filters.": "Появятся только те строки, которые соответствуют всем фильтрам.",
"Apply conditional formatting to cells in this column when formula conditions are met.": "Примените условное форматирование к ячейкам в этом столбце при выполнении условий формулы.",
"Apply conditional formatting to rows based on formulas.": "Примените условное форматирование к строкам на основе формул.",
"Cells in a reference column always identify an {{entire}} record in that table, but you may select which column from that record to show.": "Ячейки в ссылочном столбце всегда идентифицируют {{entire}} запись в этой таблице, но вы можете выбрать, какой столбец из этой записи показывать.",
"Click on “Open row styles” to apply conditional formatting to rows.": "Нажмите на “Открыть стили строк”, чтобы применить условное форматирование к строкам.",
"Click the Add New button to create new documents or workspaces, or import data.": "Нажмите кнопку Добавить, чтобы создать новые документы или рабочие области или импортировать данные.",
"Link your new widget to an existing widget on this page.": "Свяжите новый виджет с существующим виджетом на этой странице.",
"Rearrange the fields in your card by dragging and resizing cells.": "Переставляйте поля в карточке, перетаскивая и изменяя размер ячеек.",
"Reference columns are the key to {{relational}} data in Grist.": "Ссылочные столбцы являются ключом к {{relational}} данным в Grist.",
"The Raw Data page lists all data tables in your document, including summary tables and tables not included in page layouts.": "На странице необработанных данных перечислены все таблицы данных в вашем документе, включая сводные таблицы и таблицы, не включенные в макеты страниц.",
"Try out changes in a copy, then decide whether to replace the original with your edits.": "Попробуйте внести изменения в копию, затем решите, следует ли заменить оригинал вашими правками.",
"Unpin to hide the the button while keeping the filter.": "Открепите, чтобы скрыть кнопку, сохранив фильтр.",
"Useful for storing the timestamp or author of a new record, data cleaning, and more.": "Полезно для хранения метки времени или автора новой записи, очистки данных и многого другого.",
"Access Rules": "Правила доступа",
"Add New": "Добавить новое",
"Access rules give you the power to create nuanced rules to determine who can see or edit which parts of your document.": "Правила доступа дают вам возможность создавать детальные правила, определяющие, кто может просматривать или редактировать части вашего документа.",
"Use the 𝚺 icon to create summary (or pivot) tables, for totals or subtotals.": "Используйте 𝚺 значок для создания сводных таблиц для итогов или промежуточных итогов.",
"relational": "реляционный"
}
}

View File

@ -8,7 +8,10 @@
"Tutorial: Analyze & Visualize": "Посібник: аналіз та візуалізація",
"Tutorial: Create a CRM": "Підручник: створити CRM",
"Welcome to the Afterschool Program template": "Ласкаво просимо в шаблон програми позашкільної освіти",
"Welcome to the Lightweight CRM template": "Ласкаво просимо до шаблону полегшеної CRM"
"Welcome to the Lightweight CRM template": "Ласкаво просимо до шаблону полегшеної CRM",
"Check out our related tutorial for how to link data, and create high-productivity layouts.": "Перегляньте наш відповідний посібник, щоб дізнатись, як зв'язати дані та створити високопродуктивні макети.",
"Check out our related tutorial to learn how to create summary tables and charts, and to link charts dynamically.": "Перегляньте наш відповідний посібник, щоб дізнатись, як створювати підсумкові таблиці та графіки, і як налаштувати динамічний зв’язок з діаграмами.",
"Check out our related tutorial for how to model business data, use formulas, and manage complexity.": "Перегляньте наш відповідний посібник, щоб дізнатись, як моделювати бізнес-дані, використовувати формули та керувати складністю."
},
"FieldConfig": {
"Clear and reset": "Очистити та скинути",
@ -22,18 +25,25 @@
"Enter formula": "Введіть формулу",
"Formula Columns_one": "Стовпець формули",
"Formula Columns_other": "Стовпці формул",
"Mixed Behavior": "Змішана поведінка",
"Mixed Behavior": "Змішане поводження",
"Set formula": "Задайте формулу",
"Set trigger formula": "Задайте трігерну формулу",
"TRIGGER FORMULA": "ТРІГЕРНА ФОРМУЛА"
"TRIGGER FORMULA": "ТРІГЕРНА ФОРМУЛА",
"COLUMN BEHAVIOR": "ПОВОДЖЕННЯ СТОВПЦІВ",
"Convert to trigger formula": "Перетворити на тригерну формулу",
"Column options are limited in summary tables.": "Налаштування стовпців у підсумкових таблицях обмежені.",
"Convert column to data": "Перетворити стовпець у дані"
},
"FieldMenus": {
"Revert to common settings": "Повернутися до загальних налаштувань",
"Save as common settings": "Зберегти як загальні налаштування"
"Save as common settings": "Зберегти як загальні налаштування",
"Use separate settings": "Використати окремі налаштування",
"Using common settings": "Використати загальні налаштування",
"Using separate settings": "Використання окремих налаштувань"
},
"ShareMenu": {
"Manage Users": "Керувати користувачами",
"Unsaved": "Незбережено",
"Unsaved": "Не збережено",
"Access Details": "Параметри доступу",
"Back to Current": "Повернутися до поточного",
"Compare to {{termToUse}}": "Порівняти з {{termToUse}}",
@ -74,7 +84,8 @@
"Update Original": "Оновити оригінал",
"Workspace": "Робочий простір",
"You do not have write access to the selected workspace": "Ви не маєте права на запис у вибраному робочому просторі",
"You do not have write access to this site": "Ви не маєте права на запис на цьому сайті"
"You do not have write access to this site": "Ви не маєте права на запис на цьому сайті",
"However, it appears to be already identical.": "Втім, схоже, що вони вже ідентичні."
},
"SortConfig": {
"Add Column": "Додати стовпець",
@ -157,7 +168,8 @@
"Welcome to Grist, {{name}}!": "Ласкаво просимо до Grist, {{name}}!",
"Welcome to {{orgName}}": "Ласкаво просимо до {{orgName}}",
"You have read-only access to this site. Currently there are no documents.": "Ви маєте доступ до цього сайту лише для читання. Наразі документів немає.",
"personal site": "особистий сайт"
"personal site": "особистий сайт",
"{{signUp}} to save your work. ": "{{signUp}}, щоб зберегти вашу роботу. "
},
"NotifyUI": {
"Go to your free personal site": "Перейдіть на свій безкоштовний персональний сайт",
@ -184,7 +196,8 @@
"VisibleFieldsConfig": {
"Clear": "Очистити",
"Cannot drop items into Hidden Fields": "Неможливо перенести елементи у приховані поля",
"Hidden Fields cannot be reordered": "Приховані поля не можна перевпорядкувати"
"Hidden Fields cannot be reordered": "Приховані поля не можна перевпорядкувати",
"Select All": "Виділити всі"
},
"TriggerFormulas": {
"Apply to new records": "Застосувати до нових записів",
@ -211,7 +224,9 @@
"Pick a column": "Виберіть стовпець",
"selected new group data columns": "вибрані стовпці даних нової групи",
"Create separate series for each value of the selected column.": "Створіть окремі серії для кожного значення вибраного стовпця.",
"Toggle chart aggregation": "Перемикання створення діаграм"
"Toggle chart aggregation": "Перемикання створення діаграм",
"Each Y series is followed by a series for the length of error bars.": "За кожною серією Y слідує серія для довжини стовпців помилок.",
"Each Y series is followed by two series, for top and bottom error bars.": "За кожною серією Y слідують дві серії - для верхніх та нижніх стовпців помилок."
},
"ColumnFilterMenu": {
"All": "Все",
@ -239,7 +254,7 @@
"Add": "Додати",
"Enter Custom URL": "Введіть користувацький URL",
"Full document access": "Повний доступ до документа",
"Learn more about custom widgets": "Дізнайтеся більше про віджети користувача",
"Learn more about custom widgets": "Дізнайтеся більше про розширені віджети",
"No document access": "Немає доступу до документа",
"Open configuration": "Відкрита конфігурація",
"Pick a column": "Виберіть стовпець",
@ -288,7 +303,9 @@
"Allow everyone to view Access Rules.": "Дозволити всім переглядати правила доступу.",
"Permissions": "Дозволи",
"Remove column {{- colId }} from {{- tableId }} rules": "Видалити стовпець {{- colId }} з правил {{- tableId }}",
"When adding table rules, automatically add a rule to grant OWNER full access.": "При додаванні правил таблиці, автоматично додавати правило для надання ВЛАСНИКУ повного доступу."
"When adding table rules, automatically add a rule to grant OWNER full access.": "При додаванні правил таблиці, автоматично додавати правило для надання ВЛАСНИКУ повного доступу.",
"Seed rules": "Успадковані правила",
"Allow everyone to copy the entire document, or view it in full in fiddle mode.\nUseful for examples and templates, but not for sensitive data.": "Дозволити всім копіювати весь документ або переглянути його повністю в fiddle-режимі (режимі створення нових копій).\nКорисно для прикладів і шаблонів, але не для конфіденційних даних."
},
"AccountPage": {
"API": "API",
@ -306,7 +323,7 @@
"Two-factor authentication": "Двофакторна аутентифікація",
"Language": "Мова",
"Edit": "Редагувати",
"Two-factor authentication is an extra layer of security for your Grist account designed to ensure that you're the only person who can access your account, even if someone knows your password.": "Двофакторна аутентифікація - це додатковий рівень безпеки для вашого облікового запису Grist, призначений, щоб тільки ви мали доступ до вашого облікового запису, навіть якщо хтось інший знає ваш пароль."
"Two-factor authentication is an extra layer of security for your Grist account designed to ensure that you're the only person who can access your account, even if someone knows your password.": "Двофакторна аутентифікація - це додатковий рівень безпеки для вашого облікового запису Grist. Завдяки чому тільки ви будете мати доступ до вашого облікового запису, навіть якщо хтось інший дізнається ваш пароль."
},
"AccountWidget": {
"Access Details": "Відомості про доступ",
@ -352,7 +369,7 @@
},
"AppHeader": {
"Home Page": "Домашня сторінка",
"Legacy": "Успадкована версія",
"Legacy": "Застаріла версія",
"Personal Site": "Особистий сайт",
"Team Site": "Сайт команди"
},
@ -463,10 +480,12 @@
"This document's ID (for API use):": "Ідентифікатор цього документа (для використання API):",
"API": "API",
"Document ID copied to clipboard": "Ідентифікатор документа скопійований у буфер",
"Ok": "Ок"
"Ok": "Ок",
"Engine (experimental {{span}} change at own risk):": "Обчислювальна система (експериментальна версія {{span}} змінюйте на власний ризик):"
},
"DocTour": {
"No valid document tour": "Немає дійсного огляду документа"
"No valid document tour": "Немає дійсного огляду документа",
"Cannot construct a document tour from the data in this document. Ensure there is a table named GristDocTour with columns Title, Body, Placement, and Location.": "Не вдається створити огляд документа на основі даних цього документа. Переконайтеся, що існує таблиця з назвою GristDocTour зі стовпцями Title, Body, Placement і Location."
},
"DocumentUsage": {
"Data Size": "Розмір даних",
@ -475,7 +494,8 @@
"Attachments Size": "Розмір вкладених файлів",
"Contact the site owner to upgrade the plan to raise limits.": "Зв'яжіться з власником сайту, щоб оновити тариф та збільшити ліміти.",
"Usage": "Використання",
"start your 30-day free trial of the Pro plan.": "розпочніть свою 30-денну безкоштовну пробну версію тарифу Pro."
"start your 30-day free trial of the Pro plan.": "розпочніть свою 30-денну безкоштовну пробну версію тарифу Pro.",
"Usage statistics are only available to users with full access to the document data.": "Статистика використання доступна лише користувачам, які мають повний доступ до даних документа."
},
"Drafts": {
"Restore last edit": "Відновити останнє редагування",
@ -509,7 +529,8 @@
},
"Importer": {
"Merge rows that match these fields:": "Об'єднати рядки, які відповідають цим полям:",
"Update existing records": "Оновити існуючі записи"
"Update existing records": "Оновити існуючі записи",
"Select fields to match on": "Оберіть поля для зіставлення"
},
"LeftPanelCommon": {
"Help Center": "Центр допомоги"
@ -667,5 +688,257 @@
},
"AppModel": {
"This team site is suspended. Documents can be read, but not modified.": "Цей сайт команди обмежений. Документи можна читати, але редагування не доступне."
},
"WelcomeQuestions": {
"Education": "Освіта",
"Finance & Accounting": "Фінанси та облік",
"Marketing": "Маркетинг",
"Media Production": "Медіавиробництво",
"Other": "Інше",
"Product Development": "Розробка продукту",
"Research": "Дослідження",
"Sales": "Продажі",
"Type here": "Введіть тут",
"What brings you to Grist? Please help us serve you better.": "Що привело вас до Grist? Будь ласка, допоможіть зробити наш сервіс кращим.",
"HR & Management": "Управління персоналом та Менеджмент",
"IT & Technology": "IT та Технології",
"Welcome to Grist!": "Ласкаво просимо до Grist!"
},
"WidgetTitle": {
"Cancel": "Відмінити",
"DATA TABLE NAME": "ІМ'Я ТАБЛИЦІ ДАНИХ",
"Override widget title": "Перевизначити назву віджета",
"Provide a table name": "Вкажіть ім'я таблиці",
"Save": "Зберегти",
"WIDGET TITLE": "НАЗВА ВІДЖЕТА"
},
"breadcrumbs": {
"fiddle": "fiddle",
"override": "перевизначити",
"recovery mode": "режим відновлення",
"snapshot": "знімок",
"unsaved": "не збережено",
"You may make edits, but they will create a new copy and will\nnot affect the original document.": "Ви можете вносити зміни, але вони створять нову копію \nі не впливатимуть на початковий документ."
},
"duplicatePage": {
"Duplicate page {{pageName}}": "Дублювати сторінку {{pageName}}",
"Note that this does not copy data, but creates another view of the same data.": "Зауважте, що це не копіювання даних, а створення іншого подання тих самих даних."
},
"errorPages": {
"Access denied{{suffix}}": "Доступ заборонено{{suffix}}",
"Add account": "Додати обліковий запис",
"Contact support": "Зв'язатись зі службою підтримки",
"Error{{suffix}}": "Помилка{{suffix}}",
"Go to main page": "Перейти на головну сторінку",
"Page not found{{suffix}}": "Сторінка не знайдена {{suffix}}",
"Sign in": "Увійти в систему",
"Sign in again": "Увійдіть ще раз",
"Signed out{{suffix}}": "Ви вийшли з системи {{suffix}}",
"Something went wrong": "Щось пішло не так",
"There was an error: {{message}}": "Сталася помилка: {{message}}",
"There was an unknown error.": "Виникла невідома помилка.",
"You are now signed out.": "Ви вийшли з облікового запису.",
"You do not have access to this organization's documents.": "У вас немає доступу до документів цієї організації.",
"Sign in to access this organization's documents.": "Увійдіть, щоб отримати доступ до документів цієї організації.",
"The requested page could not be found.{{separator}}Please check the URL and try again.": "Потрібну сторінку не знайдено.{{separator}}Перевірте URL-адресу та повторіть ще раз.",
"You are signed in as {{email}}. You can sign in with a different account, or ask an administrator for access.": "Ви увійшли як {{email}}. Ви можете увійти під іншим обліковим записом або попросити доступ у адміністратора."
},
"menus": {
"* Workspaces are available on team plans. ": "* Робочі простори доступні в командних тарифах. ",
"Select fields": "Виберіть поля",
"Upgrade now": "Оновити зараз"
},
"modals": {
"Cancel": "Відмінити",
"Ok": "Ок",
"Save": "Зберегти"
},
"pages": {
"Duplicate Page": "Дублювати сторінку",
"Remove": "Видалити",
"Rename": "Перейменувати",
"You do not have edit access to this document": "Ви не маєте права на редагування цього документа"
},
"search": {
"Find Next ": "Знайти наступне ",
"Find Previous ": "Знайти попереднє ",
"Search in document": "Пошук у документі",
"No results": "Немає результатів"
},
"sendToDrive": {
"Sending file to Google Drive": "Надсилання файлу на Google Диск"
},
"ACLUsers": {
"Example Users": "Приклади користувачів",
"View As": "Переглянути як",
"Users from table": "Користувачі з таблиці"
},
"NTextBox": {
"true": "true",
"false": "хиба"
},
"TypeTransform": {
"Apply": "Застосувати",
"Preview": "Попередній перегляд",
"Revise": "Переглянути",
"Update formula (Shift+Enter)": "Оновити формулу (Shift+Enter)",
"Cancel": "Відмінити"
},
"CellStyle": {
"CELL STYLE": "СТИЛЬ КЛІТИНКИ",
"Default cell style": "Стиль клітинки за замовчуванням",
"Mixed style": "Змішаний стиль",
"Open row styles": "Відкрити стилі рядків",
"Cell Style": "Стиль клітинки"
},
"ChoiceTextBox": {
"CHOICES": "ВАРІАНТИ"
},
"ColumnEditor": {
"COLUMN LABEL": "ІМ'Я СТОВПЦЯ",
"COLUMN DESCRIPTION": "ОПИС СТОВПЦЯ"
},
"ColumnInfo": {
"COLUMN DESCRIPTION": "ОПИС СТОВПЦЯ",
"COLUMN ID: ": "ІДЕНТИФІКАТОР СТОВПЦЯ: ",
"Cancel": "Відмінити",
"Save": "Зберегти",
"COLUMN LABEL": "ІМ'Я СТОВПЦЯ"
},
"ConditionalStyle": {
"Add another rule": "Додайте інше правило",
"Error in style rule": "Помилка в правилі стилю",
"Row Style": "Стиль рядка",
"Rule must return True or False": "Правило має повертати True або False",
"Add conditional style": "Додайте умовний стиль"
},
"CurrencyPicker": {
"Invalid currency": "Недійсна валюта"
},
"DiscussionEditor": {
"Edit": "Редагувати",
"Marked as resolved": "Позначено як вирішене",
"Only current page": "Тільки поточна сторінка",
"Open": "Відкрити",
"Remove": "Видалити",
"Reply": "Відповісти",
"Resolve": "Вирішити",
"Save": "Зберегти",
"Show resolved comments": "Показати вирішені коментарі",
"Showing last {{nb}} comments": "Показати останні {{nb}} коментарів",
"Started discussion": "Розпочато обговорення",
"Write a comment": "Написати коментар",
"Comment": "Коментар",
"Cancel": "Відмінити",
"Reply to a comment": "Відповісти на коментар",
"Only my threads": "Тільки мої теми"
},
"FieldBuilder": {
"CELL FORMAT": "ФОРМАТ КЛІТИНКИ",
"Changing multiple column types": "Зміна кількох типів стовпців",
"DATA FROM TABLE": "ДАНІ З ТАБЛИЦІ",
"Mixed format": "Змішаний формат",
"Mixed types": "Змішані типи",
"Use separate field settings for {{colId}}": "Використати окремі налаштування поля для {{colId}}",
"Apply Formula to Data": "Застосувати формулу до даних",
"Revert field settings for {{colId}} to common": "Змінити налаштування поля для {{colId}} на загальні",
"Save field settings for {{colId}} as common": "Зберегти налаштування поля для {{colId}} як загальні"
},
"FieldEditor": {
"Unable to finish saving edited cell": "Неможливо зберегти відредаговану клітинку",
"It should be impossible to save a plain data value into a formula column": "Має бути неможливо зберегти просте значення даних у стовпець формули"
},
"FormulaEditor": {
"Column or field is required": "Стовпець або поле є обов’язковим",
"Error in the cell": "Помилка в клітинці",
"Errors in all {{numErrors}} cells": "Помилки в усіх клітинках {{numErrors}}",
"editingFormula is required": "editingFormula обов'язкове",
"Errors in {{numErrors}} of {{numCells}} cells": "Помилки в {{numErrors}} в {{numCells}} клітинках"
},
"HyperLinkEditor": {
"[link label] url": "[link label] url"
},
"NumericTextBox": {
"Currency": "Валюта",
"Decimals": "Десяткові",
"Default currency ({{defaultCurrency}})": "Валюта за замовчуванням ({{defaultCurrency}})",
"Number Format": "Числовий формат"
},
"Reference": {
"CELL FORMAT": "ФОРМАТ КЛІТИНКИ",
"Row ID": "ID рядка",
"SHOW COLUMN": "ПОКАЗАТИ СТОВПЕЦЬ"
},
"welcomeTour": {
"Add New": "Додати",
"Building up": "Створюйте",
"Configuring your document": "Налаштування вашого документа",
"Customizing columns": "Налаштування стовпців",
"Double-click or hit {{enter}} on a cell to edit it. ": "Двічі клацніть на клітинку або натисніть {{enter}}, щоб відредагувати її. ",
"Enter": "Увійти",
"Flying higher": "Летимо вище",
"Help Center": "Центр допомоги",
"Make it relational! Use the {{ref}} type to link tables. ": "Зробіть їх зв'язаними! Використовуйте тип {{ref}} для зв'язування таблиць. ",
"Reference": "Посилання",
"Sharing": "Поширення",
"Start with {{equal}} to enter a formula.": "Почати з {{equal}}, щоб ввести формулу.",
"Toggle the {{creatorPanel}} to format columns, ": "Перемкніть {{creatorPanel}}, щоб форматувати стовпці, ",
"Share": "Поділитись",
"Use {{addNew}} to add widgets, pages, or import more data. ": "Використовуйте {{addNew}}, щоб додати віджети, сторінки або імпортувати більше даних. ",
"Welcome to Grist!": "Ласкаво просимо до Grist!",
"creator panel": "панель автора",
"template library": "бібліотека шаблонів",
"Browse our {{templateLibrary}} to discover what's possible and get inspired.": "Надихайтесь і взнавайте більше про існуючі можливості, відвідавши наш {{templateLibrary}}.",
"Editing Data": "Редагування даних",
"Set formatting options, formulas, or column types, such as dates, choices, or attachments. ": "Встановити параметри форматування, формули або типи стовпців, наприклад - дати, варіанти або вкладені файли. ",
"Use the Share button ({{share}}) to share the document or export data.": "Використовуйте кнопку \"Поділитись\" ({{share}}), щоб поділитись документом або експортувати дані.",
"Use {{helpCenter}} for documentation or questions.": "Знайдіть технічну документацію чи відповіді на запитання у {{helpCenter}}.",
"convert to card view, select data, and more.": "перетворити в представлення картки, вибрати дані, та інші можливості."
},
"EditorTooltip": {
"Convert column to formula": "Перетворити стовпець у формулу"
},
"LanguageMenu": {
"Language": "Мова"
},
"GristTooltips": {
"Apply conditional formatting to rows based on formulas.": "Застосовувати умовне форматування рядків на основі формул.",
"Click the Add New button to create new documents or workspaces, or import data.": "Натисніть кнопку \"Додати\", щоб створити нові документи, робочі області або імпортувати дані.",
"Editing Card Layout": "Редагування розмітки картки",
"Learn more.": "Дізнайтесь більше.",
"Linking Widgets": "Зв'язування віджетів",
"Pinned filters are displayed as buttons above the widget.": "Закріплені фільтри відображаються як кнопки над віджетом.",
"Nested Filtering": "Вкладена фільтрація",
"Reference Columns": "Довідкові стовпці",
"Reference columns are the key to {{relational}} data in Grist.": "Довідкові стовпці є ключем до даних {{relational}} у Grist.",
"Select the table containing the data to show.": "Виділіть таблицю, що містить дані, які потрібно показати.",
"Select the table to link to.": "Виберіть таблицю, на яку потрібно зробити посилання.",
"Selecting Data": "Вибір даних",
"The total size of all data in this document, excluding attachments.": "Загальний розмір усіх даних у цьому документі, за винятком вкладених файлів.",
"They allow for one record to point (or refer) to another.": "Вони дозволяють одному запису вказувати (або посилатися) на інший.",
"This is the secret to Grist's dynamic and productive layouts.": "У цьому і полягає секрет динамічних і продуктивних макетів Grist.",
"Unpin to hide the the button while keeping the filter.": "Відкріпіть, щоб приховати кнопку, залишивши фільтр.",
"Updates every 5 minutes.": "Оновлюється кожні 5 хвилин.",
"Use the \\u{1D6BA} icon to create summary (or pivot) tables, for totals or subtotals.": "Використовуйте значок \\u{1D6BA} для створення підсумкових (або pivot) таблиць для підсумків або проміжних підсумків.",
"entire": "весь",
"relational": "зв'язаний",
"Access Rules": "Правила доступу",
"Use the 𝚺 icon to create summary (or pivot) tables, for totals or subtotals.": "Використовуйте іконку 𝚺 для створення зведених (або pivot) таблиць, для підсумків, або проміжних результатів.",
"Apply conditional formatting to cells in this column when formula conditions are met.": "Застосувати умовне форматування до клітинок у цьому стовпці, якщо виконуються умови формули.",
"Cells in a reference column always identify an {{entire}} record in that table, but you may select which column from that record to show.": "Клітинки в довідковому стовпці завжди ідентифікують запис {{entire}} у цій таблиці, але ви можете вибрати, який саме стовпець з цього запису показувати.",
"Add New": "Додати",
"Click on “Open row styles” to apply conditional formatting to rows.": "Натисніть \"Відкрити стилі рядків\", щоб застосувати умовне форматування до рядків.",
"Clicking {{EyeHideIcon}} in each cell hides the field from this view without deleting it.": "Натискання {{EyeHideIcon}} у кожній клітинці робить поле прихованим, але не видалає його.",
"Link your new widget to an existing widget on this page.": "Зв'яжіть свій новий віджет з існуючим віджетом на цій сторінці.",
"Pinning Filters": "Закріплення фільтрів",
"Formulas that trigger in certain cases, and store the calculated value as data.": "Формули, які запускаються в певних випадках і зберігають обчислене значення як дані.",
"Only those rows will appear which match all of the filters.": "З'являться лише ті рядки, які відповідають усім фільтрам.",
"Raw Data page": "Сторінка необроблених даних",
"Rearrange the fields in your card by dragging and resizing cells.": "Змінюйте розташування полів у вашій картці, перетягуючи клітинки та змінюючи їх розмір.",
"The Raw Data page lists all data tables in your document, including summary tables and tables not included in page layouts.": "Сторінка «Необроблені дані» містить список усіх таблиць даних у вашому документі, включно з підсумковими таблицями та таблицями, не включеними до макетів сторінок.",
"Useful for storing the timestamp or author of a new record, data cleaning, and more.": "Корисно для збереження позначки часу або автора нового запису, очищення даних тощо.",
"You can filter by more than one column.": "Ви можете фільтрувати за кількома стовпцями.",
"Try out changes in a copy, then decide whether to replace the original with your edits.": "Спробуйте змінити копію, а потім вирішіть, чи слід замінювати оригінал своїми правками.",
"Access rules give you the power to create nuanced rules to determine who can see or edit which parts of your document.": "Правила доступу дають вам можливість створювати детальні правила, щоб визначити, хто може бачити або редагувати (та які) частини вашого документа."
}
}

172
yarn.lock
View File

@ -218,22 +218,6 @@
resolved "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz"
integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==
"@electron/get@^1.14.1":
version "1.14.1"
resolved "https://registry.npmjs.org/@electron/get/-/get-1.14.1.tgz"
integrity sha512-BrZYyL/6m0ZXz/lDxy/nlVhQz+WF+iPS6qXolEU8atw7h6v1aYkjwJZ63m+bJMBTxDE66X+r2tPS4a/8C82sZw==
dependencies:
debug "^4.1.1"
env-paths "^2.2.0"
fs-extra "^8.1.0"
got "^9.6.0"
progress "^2.0.3"
semver "^6.2.0"
sumchecker "^3.0.1"
optionalDependencies:
global-agent "^3.0.0"
global-tunnel-ng "^2.7.1"
"@eslint/eslintrc@^1.3.0":
version "1.4.1"
resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.4.1.tgz#af58772019a2d271b7e2d4c23ff4ddcba3ccfb3e"
@ -831,11 +815,6 @@
resolved "https://registry.npmjs.org/@types/node/-/node-14.17.6.tgz"
integrity sha512-iBxsxU7eswQDGhlr3AiamBxOssaYxbM+NKXVil8jg9yFXvrfEFbDumLD/2dMTB+zYyg7w+Xjt8yuxfdbUHAtcQ==
"@types/node@^16.11.26":
version "16.11.58"
resolved "https://registry.npmjs.org/@types/node/-/node-16.11.58.tgz"
integrity sha512-uMVxJ111wpHzkx/vshZFb6Qni3BOMnlWLq7q9jrwej7Yw/KvjsEbpxCCxw+hLKxexFMc8YmpG8J9tnEe/rKsIg==
"@types/parse5@*":
version "7.0.0"
resolved "https://registry.npmjs.org/@types/parse5/-/parse5-7.0.0.tgz"
@ -1780,11 +1759,6 @@ body-parser@1.18.3:
raw-body "2.3.3"
type-is "~1.6.16"
boolean@^3.0.1:
version "3.2.0"
resolved "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz"
integrity sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==
bootstrap-datepicker@1.9.0:
version "1.9.0"
resolved "https://registry.npmjs.org/bootstrap-datepicker/-/bootstrap-datepicker-1.9.0.tgz"
@ -2539,14 +2513,6 @@ concat-stream@~1.5.0, concat-stream@~1.5.1:
readable-stream "~2.0.0"
typedarray "~0.0.5"
config-chain@^1.1.11:
version "1.1.13"
resolved "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz"
integrity sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==
dependencies:
ini "^1.3.4"
proto-list "~1.2.1"
configstore@^5.0.1:
version "5.0.1"
resolved "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz"
@ -2979,11 +2945,6 @@ detect-libc@^2.0.0:
resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.1.tgz#e1897aa88fa6ad197862937fbc0441ef352ee0cd"
integrity sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==
detect-node@^2.0.4:
version "2.1.0"
resolved "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz"
integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==
detective@^4.0.0:
version "4.7.1"
resolved "https://registry.npmjs.org/detective/-/detective-4.7.1.tgz"
@ -3126,15 +3087,6 @@ electron-to-chromium@^1.4.251:
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz#61046d1e4cab3a25238f6bf7413795270f125592"
integrity sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==
electron@19.0.9:
version "19.0.9"
resolved "https://registry.npmjs.org/electron/-/electron-19.0.9.tgz"
integrity sha512-ooEwrv8Y7NSzdhKcl6kPCYecnzcg5nFWuS5ryG+VFH3MMBR8zXh9nW2wLsZrBz6OGUxXrcc5BKBC7dA8C6RhGQ==
dependencies:
"@electron/get" "^1.14.1"
"@types/node" "^16.11.26"
extract-zip "^1.0.3"
elliptic@^6.0.0, elliptic@^6.5.2:
version "6.5.4"
resolved "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz"
@ -3168,7 +3120,7 @@ encode-utf8@^1.0.3:
resolved "https://registry.npmjs.org/encode-utf8/-/encode-utf8-1.0.3.tgz"
integrity sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw==
encodeurl@^1.0.2, encodeurl@~1.0.2:
encodeurl@~1.0.2:
version "1.0.2"
resolved "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz"
integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=
@ -3207,7 +3159,7 @@ entities@^4.3.0:
env-paths@^2.2.0:
version "2.2.1"
resolved "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz"
resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2"
integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==
envinfo@^7.7.3:
@ -3664,7 +3616,7 @@ extend@^3.0.0, extend@^3.0.2, extend@~3.0.2:
resolved "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz"
integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
extract-zip@^1.0.3, extract-zip@^1.6.7:
extract-zip@^1.6.7:
version "1.7.0"
resolved "https://registry.npmjs.org/extract-zip/-/extract-zip-1.7.0.tgz"
integrity sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==
@ -3921,7 +3873,7 @@ fs-extra@^4.0.2, fs-extra@^4.0.3:
jsonfile "^4.0.0"
universalify "^0.1.0"
fs-extra@^8.0.1, fs-extra@^8.1.0:
fs-extra@^8.0.1:
version "8.1.0"
resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz"
integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==
@ -4192,18 +4144,6 @@ glob@~3.2.7:
inherits "2"
minimatch "0.3"
global-agent@^3.0.0:
version "3.0.0"
resolved "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz"
integrity sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==
dependencies:
boolean "^3.0.1"
es6-error "^4.1.1"
matcher "^3.0.0"
roarr "^2.15.3"
semver "^7.3.2"
serialize-error "^7.0.1"
global-dirs@^2.0.1:
version "2.0.1"
resolved "https://registry.npmjs.org/global-dirs/-/global-dirs-2.0.1.tgz"
@ -4211,16 +4151,6 @@ global-dirs@^2.0.1:
dependencies:
ini "^1.3.5"
global-tunnel-ng@^2.7.1:
version "2.7.1"
resolved "https://registry.npmjs.org/global-tunnel-ng/-/global-tunnel-ng-2.7.1.tgz"
integrity sha512-4s+DyciWBV0eK148wqXxcmVAbFVPqtc3sEtUE/GTQfuU80rySLcMhUmHKSHI7/LDj8q0gDYI1lIhRRB7ieRAqg==
dependencies:
encodeurl "^1.0.2"
lodash "^4.17.10"
npm-conf "^1.1.3"
tunnel "^0.0.6"
globals@^11.1.0:
version "11.12.0"
resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e"
@ -4233,13 +4163,6 @@ globals@^13.15.0, globals@^13.19.0:
dependencies:
type-fest "^0.20.2"
globalthis@^1.0.1:
version "1.0.3"
resolved "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz"
integrity sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==
dependencies:
define-properties "^1.1.3"
globby@^11.1.0:
version "11.1.0"
resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b"
@ -4793,11 +4716,6 @@ inherits@2.0.3:
resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz"
integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
ini@^1.3.4:
version "1.3.8"
resolved "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz"
integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==
ini@^1.3.5, ini@~1.3.0:
version "1.3.7"
resolved "https://registry.npmjs.org/ini/-/ini-1.3.7.tgz"
@ -5331,7 +5249,7 @@ json-stream@^1.0.0:
resolved "https://registry.yarnpkg.com/json-stream/-/json-stream-1.0.0.tgz#1a3854e28d2bbeeab31cc7ddf683d2ddc5652708"
integrity sha512-H/ZGY0nIAg3QcOwE1QN/rK/Fa7gJn7Ii5obwp6zyPO4xiPNwpIMjqy2gwjBEGqzkF/vSWEIBQCBuN19hYiL6Qg==
json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1:
json-stringify-safe@~5.0.1:
version "5.0.1"
resolved "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz"
integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=
@ -5671,7 +5589,7 @@ lodash.uniq@^4.5.0:
resolved "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz"
integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=
lodash@4.17.21, lodash@^4.0.0, lodash@^4.17.10, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.21, lodash@^4.7.0:
lodash@4.17.21, lodash@^4.0.0, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.21, lodash@^4.7.0:
version "4.17.21"
resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
@ -5753,13 +5671,6 @@ make-fetch-happen@^9.1.0:
socks-proxy-agent "^6.0.0"
ssri "^8.0.0"
matcher@^3.0.0:
version "3.0.0"
resolved "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz"
integrity sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==
dependencies:
escape-string-regexp "^4.0.0"
md5.js@^1.3.4:
version "1.3.5"
resolved "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz"
@ -6334,14 +6245,6 @@ now-and-later@^2.0.0:
dependencies:
once "^1.3.2"
npm-conf@^1.1.3:
version "1.1.3"
resolved "https://registry.npmjs.org/npm-conf/-/npm-conf-1.1.3.tgz"
integrity sha512-Yic4bZHJOt9RCFbRP3GgpqhScOY4HH3V2P8yBj6CeYq118Qr+BLXqT2JvpJ00mryLESpgOxf5XlFv4ZjXxLScw==
dependencies:
config-chain "^1.1.11"
pify "^3.0.0"
npm-run-path@^3.1.0:
version "3.1.0"
resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-3.1.0.tgz"
@ -6906,11 +6809,6 @@ process@~0.11.0:
resolved "https://registry.npmjs.org/process/-/process-0.11.10.tgz"
integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI=
progress@^2.0.3:
version "2.0.3"
resolved "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz"
integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==
promise-inflight@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3"
@ -6924,11 +6822,6 @@ promise-retry@^2.0.1:
err-code "^2.0.2"
retry "^0.12.0"
proto-list@~1.2.1:
version "1.2.4"
resolved "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz"
integrity sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==
proxy-addr@~2.0.4:
version "2.0.6"
resolved "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz"
@ -7458,18 +7351,6 @@ ripemd160@^2.0.0, ripemd160@^2.0.1:
hash-base "^3.0.0"
inherits "^2.0.1"
roarr@^2.15.3:
version "2.15.4"
resolved "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz"
integrity sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==
dependencies:
boolean "^3.0.1"
detect-node "^2.0.4"
globalthis "^1.0.1"
json-stringify-safe "^5.0.1"
semver-compare "^1.0.0"
sprintf-js "^1.1.2"
run-parallel@^1.1.9:
version "1.2.0"
resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee"
@ -7552,11 +7433,6 @@ selenium-webdriver@^4.0.0-alpha.1:
tmp "^0.2.1"
ws "^7.3.1"
semver-compare@^1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz"
integrity sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==
semver-diff@^3.1.1:
version "3.1.1"
resolved "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz"
@ -7574,13 +7450,6 @@ semver@^6.0.0, semver@^6.2.0, semver@^6.3.0:
resolved "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz"
integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
semver@^7.3.2:
version "7.3.7"
resolved "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz"
integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==
dependencies:
lru-cache "^6.0.0"
semver@^7.3.5, semver@^7.3.7:
version "7.3.8"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798"
@ -7607,13 +7476,6 @@ send@0.16.2:
range-parser "~1.2.0"
statuses "~1.4.0"
serialize-error@^7.0.1:
version "7.0.1"
resolved "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz"
integrity sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==
dependencies:
type-fest "^0.13.1"
serialize-javascript@^6.0.0:
version "6.0.0"
resolved "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz"
@ -7838,11 +7700,6 @@ split2@^4.1.0:
resolved "https://registry.npmjs.org/split2/-/split2-4.1.0.tgz"
integrity sha512-VBiJxFkxiXRlUIeyMQi8s4hgvKCSjtknJv/LVYbrgALPwf5zSKmEwV9Lst25AkvMDnvxODugjdl6KZgwKM1WYQ==
sprintf-js@^1.1.2:
version "1.1.2"
resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz"
integrity sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==
sprintf-js@~1.0.2:
version "1.0.3"
resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz"
@ -8096,13 +7953,6 @@ subarg@^1.0.0:
dependencies:
minimist "^1.1.0"
sumchecker@^3.0.1:
version "3.0.1"
resolved "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz"
integrity sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==
dependencies:
debug "^4.1.0"
supports-color@5.4.0:
version "5.4.0"
resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz"
@ -8476,11 +8326,6 @@ tunnel-agent@^0.6.0:
dependencies:
safe-buffer "^5.0.1"
tunnel@^0.0.6:
version "0.0.6"
resolved "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz"
integrity sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==
tweetnacl@^0.14.3, tweetnacl@~0.14.0:
version "0.14.5"
resolved "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz"
@ -8505,11 +8350,6 @@ type-detect@4.0.8, type-detect@^4.0.0, type-detect@^4.0.5, type-detect@^4.0.8:
resolved "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz"
integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==
type-fest@^0.13.1:
version "0.13.1"
resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz"
integrity sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==
type-fest@^0.20.2:
version "0.20.2"
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4"