From be507f98e63f4f86f7d1fa1d045ad0f3bcbc0f4c Mon Sep 17 00:00:00 2001
From: russellwheatley
Date: Tue, 7 Jan 2025 10:30:04 +0000
Subject: [PATCH 001/115] init
---
packages/vertexai/README.md | 54 ++++++++++++++++++++++++++++++++++
packages/vertexai/package.json | 32 ++++++++++++++++++++
2 files changed, 86 insertions(+)
create mode 100644 packages/vertexai/README.md
create mode 100644 packages/vertexai/package.json
diff --git a/packages/vertexai/README.md b/packages/vertexai/README.md
new file mode 100644
index 0000000000..49783ab637
--- /dev/null
+++ b/packages/vertexai/README.md
@@ -0,0 +1,54 @@
+
+
+ 
+
+
React Native Firebase - Cloud Storage
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+---
+
+Cloud Storage for Firebase is a powerful, simple, and cost-effective object storage service built for Google scale. The Firebase SDKs for Cloud Storage add Google security to file uploads and downloads for your Firebase apps, regardless of network quality. You can use our SDKs to store images, audio, video, or other user-generated content. On the server, you can use [Google Cloud Storage](https://cloud.google.com/storage), to access the same files.
+
+[> Learn More](https://firebase.google.com/products/storage/)
+
+## Installation
+
+Requires `@react-native-firebase/app` to be installed.
+
+```bash
+yarn add @react-native-firebase/storage
+```
+
+## Documentation
+
+- [Quick Start](https://rnfirebase.io/storage/usage)
+- [Reference](https://rnfirebase.io/reference/storage)
+
+## License
+
+- See [LICENSE](/LICENSE)
+
+---
+
+
+
+
+ Built and maintained with 💛 by Invertase.
+
+
+
+---
diff --git a/packages/vertexai/package.json b/packages/vertexai/package.json
new file mode 100644
index 0000000000..20e216010d
--- /dev/null
+++ b/packages/vertexai/package.json
@@ -0,0 +1,32 @@
+{
+ "name": "@react-native-firebase/vertexai",
+ "version": "0.0.1",
+ "author": "Invertase (http://invertase.io)",
+ "description": "React Native Firebase - Vertex AI is a fully-managed, unified AI development platform for building and using generative AI",
+ "main": "lib/index.js",
+ "types": "lib/index.d.ts",
+ "scripts": {
+ "build": "genversion --semi lib/version.js",
+ "build:clean": "rimraf android/build && rimraf ios/build",
+ "prepare": "yarn run build"
+ },
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/invertase/react-native-firebase/tree/main/packages/vertexai"
+ },
+ "license": "Apache-2.0",
+ "keywords": [
+ "react",
+ "react-native",
+ "firebase",
+ "vertexai",
+ "gemini",
+ "generative-ai"
+ ],
+ "peerDependencies": {
+ "@react-native-firebase/app": "21.6.2"
+ },
+ "publishConfig": {
+ "access": "public"
+ }
+}
From bbef576837b1083d403ae03bb464c14dd36f19ed Mon Sep 17 00:00:00 2001
From: russellwheatley
Date: Tue, 7 Jan 2025 10:37:41 +0000
Subject: [PATCH 002/115] update README
---
packages/vertexai/README.md | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/packages/vertexai/README.md b/packages/vertexai/README.md
index 49783ab637..3ba225ba15 100644
--- a/packages/vertexai/README.md
+++ b/packages/vertexai/README.md
@@ -2,13 +2,13 @@

- React Native Firebase - Cloud Storage
+ React Native Firebase - Vertex AI
-
-
-
+
+
+
@@ -21,22 +21,22 @@
---
-Cloud Storage for Firebase is a powerful, simple, and cost-effective object storage service built for Google scale. The Firebase SDKs for Cloud Storage add Google security to file uploads and downloads for your Firebase apps, regardless of network quality. You can use our SDKs to store images, audio, video, or other user-generated content. On the server, you can use [Google Cloud Storage](https://cloud.google.com/storage), to access the same files.
+Vertex AI is a fully-managed, unified AI development platform for building and using generative AI. Access and utilize Vertex AI Studio, Agent Builder, and 150+ foundation models including Gemini 1.5 Pro and Gemini 1.5 Flash.
-[> Learn More](https://firebase.google.com/products/storage/)
+[> Learn More](https://firebase.google.com/docs/vertex-ai/)
## Installation
Requires `@react-native-firebase/app` to be installed.
```bash
-yarn add @react-native-firebase/storage
+yarn add @react-native-firebase/vertexai
```
## Documentation
-- [Quick Start](https://rnfirebase.io/storage/usage)
-- [Reference](https://rnfirebase.io/reference/storage)
+- [Quick Start](https://rnfirebase.io/vertexai/usage)
+- [Reference](https://rnfirebase.io/reference/vertexai)
## License
From 3c9eef308afbee68eba641a83d4b2c2c1bc98fc8 Mon Sep 17 00:00:00 2001
From: russellwheatley
Date: Tue, 7 Jan 2025 10:38:33 +0000
Subject: [PATCH 003/115] .npmignore
---
packages/vertexai/.npmignore | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
create mode 100644 packages/vertexai/.npmignore
diff --git a/packages/vertexai/.npmignore b/packages/vertexai/.npmignore
new file mode 100644
index 0000000000..e1c829bc0b
--- /dev/null
+++ b/packages/vertexai/.npmignore
@@ -0,0 +1,26 @@
+
+# OS-specific files
+.DS_Store
+.DS_Store?
+._*
+.Spotlight-V100
+.Trashes
+ehthumbs.db
+Thumbs.dbandroid/gradle
+android/gradlew
+android/build
+android/gradlew.bat
+android/gradle/
+
+.idea
+coverage
+yarn.lock
+e2e/
+.github
+.vscode
+.nyc_output
+android/.settings
+*.coverage.json
+.circleci
+.eslintignore
+type-test.ts
From 304c1946386c457ea32f2da83eacdf3c439ef41f Mon Sep 17 00:00:00 2001
From: russellwheatley
Date: Tue, 7 Jan 2025 10:39:06 +0000
Subject: [PATCH 004/115] license
---
packages/vertexai/LICENSE | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
create mode 100644 packages/vertexai/LICENSE
diff --git a/packages/vertexai/LICENSE b/packages/vertexai/LICENSE
new file mode 100644
index 0000000000..ef3ed44f06
--- /dev/null
+++ b/packages/vertexai/LICENSE
@@ -0,0 +1,32 @@
+Apache-2.0 License
+------------------
+
+Copyright (c) 2016-present Invertase Limited & Contributors
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this library except in compliance with the License.
+
+You may obtain a copy of the Apache-2.0 License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+
+Creative Commons Attribution 3.0 License
+----------------------------------------
+
+Copyright (c) 2016-present Invertase Limited & Contributors
+
+Documentation and other instructional materials provided for this project
+(including on a separate documentation repository or it's documentation website) are
+licensed under the Creative Commons Attribution 3.0 License. Code samples/blocks
+contained therein are licensed under the Apache License, Version 2.0 (the "License"), as above.
+
+You may obtain a copy of the Creative Commons Attribution 3.0 License at
+
+ https://creativecommons.org/licenses/by/3.0/
From d713b4e87007ce1de4ae4afddfc8033ec4844f5b Mon Sep 17 00:00:00 2001
From: russellwheatley
Date: Wed, 8 Jan 2025 14:30:44 +0000
Subject: [PATCH 005/115] initial port over of vertexAI from firebase-js-sdk
---
packages/vertexai/lib/constants.ts | 32 ++
packages/vertexai/lib/errors.ts | 66 ++++
packages/vertexai/lib/index.ts | 73 +++++
packages/vertexai/lib/logger.ts | 247 +++++++++++++++
.../lib/methods/chat-session-helpers.ts | 116 +++++++
packages/vertexai/lib/methods/chat-session.ts | 182 +++++++++++
packages/vertexai/lib/methods/count-tokens.ts | 37 +++
.../vertexai/lib/methods/generate-content.ts | 66 ++++
.../vertexai/lib/models/generative-model.ts | 179 +++++++++++
packages/vertexai/lib/public-types.ts | 40 +++
.../vertexai/lib/requests/request-helpers.ts | 115 +++++++
packages/vertexai/lib/requests/request.ts | 230 ++++++++++++++
.../vertexai/lib/requests/response-helpers.ts | 198 ++++++++++++
.../vertexai/lib/requests/schema-builder.ts | 292 ++++++++++++++++++
.../vertexai/lib/requests/stream-reader.ts | 205 ++++++++++++
packages/vertexai/lib/service.ts | 50 +++
packages/vertexai/lib/types/content.ts | 162 ++++++++++
packages/vertexai/lib/types/enums.ts | 139 +++++++++
packages/vertexai/lib/types/error.ts | 98 ++++++
packages/vertexai/lib/types/index.ts | 23 ++
packages/vertexai/lib/types/internal.ts | 41 +++
packages/vertexai/lib/types/requests.ts | 198 ++++++++++++
packages/vertexai/lib/types/responses.ts | 209 +++++++++++++
packages/vertexai/lib/types/schema.ts | 103 ++++++
24 files changed, 3101 insertions(+)
create mode 100644 packages/vertexai/lib/constants.ts
create mode 100644 packages/vertexai/lib/errors.ts
create mode 100644 packages/vertexai/lib/index.ts
create mode 100644 packages/vertexai/lib/logger.ts
create mode 100644 packages/vertexai/lib/methods/chat-session-helpers.ts
create mode 100644 packages/vertexai/lib/methods/chat-session.ts
create mode 100644 packages/vertexai/lib/methods/count-tokens.ts
create mode 100644 packages/vertexai/lib/methods/generate-content.ts
create mode 100644 packages/vertexai/lib/models/generative-model.ts
create mode 100644 packages/vertexai/lib/public-types.ts
create mode 100644 packages/vertexai/lib/requests/request-helpers.ts
create mode 100644 packages/vertexai/lib/requests/request.ts
create mode 100644 packages/vertexai/lib/requests/response-helpers.ts
create mode 100644 packages/vertexai/lib/requests/schema-builder.ts
create mode 100644 packages/vertexai/lib/requests/stream-reader.ts
create mode 100644 packages/vertexai/lib/service.ts
create mode 100644 packages/vertexai/lib/types/content.ts
create mode 100644 packages/vertexai/lib/types/enums.ts
create mode 100644 packages/vertexai/lib/types/error.ts
create mode 100644 packages/vertexai/lib/types/index.ts
create mode 100644 packages/vertexai/lib/types/internal.ts
create mode 100644 packages/vertexai/lib/types/requests.ts
create mode 100644 packages/vertexai/lib/types/responses.ts
create mode 100644 packages/vertexai/lib/types/schema.ts
diff --git a/packages/vertexai/lib/constants.ts b/packages/vertexai/lib/constants.ts
new file mode 100644
index 0000000000..357e6c4e77
--- /dev/null
+++ b/packages/vertexai/lib/constants.ts
@@ -0,0 +1,32 @@
+/**
+ * @license
+ * Copyright 2024 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { version } from '../package.json';
+
+export const VERTEX_TYPE = 'vertexAI';
+
+export const DEFAULT_LOCATION = 'us-central1';
+
+export const DEFAULT_BASE_URL = 'https://firebasevertexai.googleapis.com';
+
+export const DEFAULT_API_VERSION = 'v1beta';
+
+export const PACKAGE_VERSION = version;
+
+export const LANGUAGE_TAG = 'gl-js';
+
+export const DEFAULT_FETCH_TIMEOUT_MS = 180 * 1000;
diff --git a/packages/vertexai/lib/errors.ts b/packages/vertexai/lib/errors.ts
new file mode 100644
index 0000000000..0603b0350d
--- /dev/null
+++ b/packages/vertexai/lib/errors.ts
@@ -0,0 +1,66 @@
+/**
+ * @license
+ * Copyright 2024 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { FirebaseError } from '@firebase/util';
+import { VertexAIErrorCode, CustomErrorData } from './types';
+import { VERTEX_TYPE } from './constants';
+
+/**
+ * Error class for the Vertex AI in Firebase SDK.
+ *
+ * @public
+ */
+export class VertexAIError extends FirebaseError {
+ /**
+ * Constructs a new instance of the `VertexAIError` class.
+ *
+ * @param code - The error code from {@link VertexAIErrorCode}
.
+ * @param message - A human-readable message describing the error.
+ * @param customErrorData - Optional error data.
+ */
+ constructor(
+ readonly code: VertexAIErrorCode,
+ message: string,
+ readonly customErrorData?: CustomErrorData,
+ ) {
+ // Match error format used by FirebaseError from ErrorFactory
+ const service = VERTEX_TYPE;
+ const serviceName = 'VertexAI';
+ const fullCode = `${service}/${code}`;
+ const fullMessage = `${serviceName}: ${message} (${fullCode})`;
+ super(code, fullMessage);
+
+ // FirebaseError initializes a stack trace, but it assumes the error is created from the error
+ // factory. Since we break this assumption, we set the stack trace to be originating from this
+ // constructor.
+ // This is only supported in V8.
+ if (Error.captureStackTrace) {
+ // Allows us to initialize the stack trace without including the constructor itself at the
+ // top level of the stack trace.
+ Error.captureStackTrace(this, VertexAIError);
+ }
+
+ // Allows instanceof VertexAIError in ES5/ES6
+ // https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work
+ // TODO(dlarocque): Replace this with `new.target`: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-2.html#support-for-newtarget
+ // which we can now use since we no longer target ES5.
+ Object.setPrototypeOf(this, VertexAIError.prototype);
+
+ // Since Error is an interface, we don't inherit toString and so we define it ourselves.
+ this.toString = () => fullMessage;
+ }
+}
diff --git a/packages/vertexai/lib/index.ts b/packages/vertexai/lib/index.ts
new file mode 100644
index 0000000000..20ac5384a1
--- /dev/null
+++ b/packages/vertexai/lib/index.ts
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2016-present Invertase Limited & Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this library except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+import { getApp, FirebaseApp } from '@firebase/app';
+import { ModelParams, RequestOptions, VertexAIErrorCode } from './types';
+import { DEFAULT_LOCATION } from './constants';
+import { VertexAI, VertexAIOptions } from './public-types';
+// import { ModelParams, RequestOptions, VertexAIErrorCode } from './types';
+import { VertexAIError } from './errors';
+import { GenerativeModel } from './models/generative-model';
+
+export { ChatSession } from './methods/chat-session';
+export * from './requests/schema-builder';
+
+export { GenerativeModel };
+
+export { VertexAIError };
+
+/**
+ * Returns a {@link VertexAI}
instance for the given app.
+ *
+ * @public
+ *
+ * @param app - The {@link @firebase/app#FirebaseApp} to use.
+ */
+export function getVertexAI(app: FirebaseApp = getApp(), options?: VertexAIOptions): VertexAI {
+ // app = getModularInstance(app);
+ // Dependencies
+ // const vertexProvider: Provider<'vertexAI'> = _getProvider(app, VERTEX_TYPE);
+
+ // TODO - app used to get location and later the projectId
+ // return vertexProvider.getImmediate({
+ // identifier: options?.location || DEFAULT_LOCATION,
+ // });
+ return {
+ app,
+ location: options?.location || DEFAULT_LOCATION,
+ };
+}
+
+/**
+ * Returns a {@link GenerativeModel}
class with methods for inference
+ * and other functionality.
+ *
+ * @public
+ */
+export function getGenerativeModel(
+ vertexAI: VertexAI,
+ modelParams: ModelParams,
+ requestOptions?: RequestOptions,
+): GenerativeModel {
+ if (!modelParams.model) {
+ throw new VertexAIError(
+ VertexAIErrorCode.NO_MODEL,
+ `Must provide a model name. Example: getGenerativeModel({ model: 'my-model-name' })`,
+ );
+ }
+ return new GenerativeModel(vertexAI, modelParams, requestOptions);
+}
diff --git a/packages/vertexai/lib/logger.ts b/packages/vertexai/lib/logger.ts
new file mode 100644
index 0000000000..681e9f8ac0
--- /dev/null
+++ b/packages/vertexai/lib/logger.ts
@@ -0,0 +1,247 @@
+/*
+ * Copyright (c) 2016-present Invertase Limited & Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this library except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+export type LogLevelString = 'debug' | 'verbose' | 'info' | 'warn' | 'error' | 'silent';
+
+export interface LogOptions {
+ level: LogLevelString;
+}
+
+export type LogCallback = (callbackParams: LogCallbackParams) => void;
+
+export interface LogCallbackParams {
+ level: LogLevelString;
+ message: string;
+ args: unknown[];
+ type: string;
+}
+
+/**
+ * A container for all of the Logger instances
+ */
+export const instances: Logger[] = [];
+
+/**
+ * The JS SDK supports 5 log levels and also allows a user the ability to
+ * silence the logs altogether.
+ *
+ * The order is a follows:
+ * DEBUG < VERBOSE < INFO < WARN < ERROR
+ *
+ * All of the log types above the current log level will be captured (i.e. if
+ * you set the log level to `INFO`, errors will still be logged, but `DEBUG` and
+ * `VERBOSE` logs will not)
+ */
+export enum LogLevel {
+ DEBUG,
+ VERBOSE,
+ INFO,
+ WARN,
+ ERROR,
+ SILENT,
+}
+
+const levelStringToEnum: { [key in LogLevelString]: LogLevel } = {
+ debug: LogLevel.DEBUG,
+ verbose: LogLevel.VERBOSE,
+ info: LogLevel.INFO,
+ warn: LogLevel.WARN,
+ error: LogLevel.ERROR,
+ silent: LogLevel.SILENT,
+};
+
+/**
+ * The default log level
+ */
+const defaultLogLevel: LogLevel = LogLevel.INFO;
+
+/**
+ * We allow users the ability to pass their own log handler. We will pass the
+ * type of log, the current log level, and any other arguments passed (i.e. the
+ * messages that the user wants to log) to this function.
+ */
+export type LogHandler = (loggerInstance: Logger, logType: LogLevel, ...args: unknown[]) => void;
+
+/**
+ * By default, `console.debug` is not displayed in the developer console (in
+ * chrome). To avoid forcing users to have to opt-in to these logs twice
+ * (i.e. once for firebase, and once in the console), we are sending `DEBUG`
+ * logs to the `console.log` function.
+ */
+const ConsoleMethod = {
+ [LogLevel.DEBUG]: 'log',
+ [LogLevel.VERBOSE]: 'log',
+ [LogLevel.INFO]: 'info',
+ [LogLevel.WARN]: 'warn',
+ [LogLevel.ERROR]: 'error',
+};
+
+/**
+ * The default log handler will forward DEBUG, VERBOSE, INFO, WARN, and ERROR
+ * messages on to their corresponding console counterparts (if the log method
+ * is supported by the current log level)
+ */
+const defaultLogHandler: LogHandler = (instance, logType, ...args): void => {
+ if (logType < instance.logLevel) {
+ return;
+ }
+ const now = new Date().toISOString();
+ const method = ConsoleMethod[logType as keyof typeof ConsoleMethod];
+ if (method) {
+ console[method as 'log' | 'info' | 'warn' | 'error'](`[${now}] ${instance.name}:`, ...args);
+ } else {
+ throw new Error(`Attempted to log a message with an invalid logType (value: ${logType})`);
+ }
+};
+
+export class Logger {
+ /**
+ * Gives you an instance of a Logger to capture messages according to
+ * Firebase's logging scheme.
+ *
+ * @param name The name that the logs will be associated with
+ */
+ constructor(public name: string) {
+ /**
+ * Capture the current instance for later use
+ */
+ instances.push(this);
+ }
+
+ /**
+ * The log level of the given Logger instance.
+ */
+ private _logLevel = defaultLogLevel;
+
+ get logLevel(): LogLevel {
+ return this._logLevel;
+ }
+
+ set logLevel(val: LogLevel) {
+ if (!(val in LogLevel)) {
+ throw new TypeError(`Invalid value "${val}" assigned to \`logLevel\``);
+ }
+ this._logLevel = val;
+ }
+
+ // Workaround for setter/getter having to be the same type.
+ setLogLevel(val: LogLevel | LogLevelString): void {
+ this._logLevel = typeof val === 'string' ? levelStringToEnum[val] : val;
+ }
+
+ /**
+ * The main (internal) log handler for the Logger instance.
+ * Can be set to a new function in internal package code but not by user.
+ */
+ private _logHandler: LogHandler = defaultLogHandler;
+ get logHandler(): LogHandler {
+ return this._logHandler;
+ }
+ set logHandler(val: LogHandler) {
+ if (typeof val !== 'function') {
+ throw new TypeError('Value assigned to `logHandler` must be a function');
+ }
+ this._logHandler = val;
+ }
+
+ /**
+ * The optional, additional, user-defined log handler for the Logger instance.
+ */
+ private _userLogHandler: LogHandler | null = null;
+ get userLogHandler(): LogHandler | null {
+ return this._userLogHandler;
+ }
+ set userLogHandler(val: LogHandler | null) {
+ this._userLogHandler = val;
+ }
+
+ /**
+ * The functions below are all based on the `console` interface
+ */
+
+ debug(...args: unknown[]): void {
+ this._userLogHandler && this._userLogHandler(this, LogLevel.DEBUG, ...args);
+ this._logHandler(this, LogLevel.DEBUG, ...args);
+ }
+ log(...args: unknown[]): void {
+ this._userLogHandler && this._userLogHandler(this, LogLevel.VERBOSE, ...args);
+ this._logHandler(this, LogLevel.VERBOSE, ...args);
+ }
+ info(...args: unknown[]): void {
+ this._userLogHandler && this._userLogHandler(this, LogLevel.INFO, ...args);
+ this._logHandler(this, LogLevel.INFO, ...args);
+ }
+ warn(...args: unknown[]): void {
+ this._userLogHandler && this._userLogHandler(this, LogLevel.WARN, ...args);
+ this._logHandler(this, LogLevel.WARN, ...args);
+ }
+ error(...args: unknown[]): void {
+ this._userLogHandler && this._userLogHandler(this, LogLevel.ERROR, ...args);
+ this._logHandler(this, LogLevel.ERROR, ...args);
+ }
+}
+
+export function setLogLevel(level: LogLevelString | LogLevel): void {
+ instances.forEach(inst => {
+ inst.setLogLevel(level);
+ });
+}
+
+export function setUserLogHandler(logCallback: LogCallback | null, options?: LogOptions): void {
+ for (const instance of instances) {
+ let customLogLevel: LogLevel | null = null;
+ if (options && options.level) {
+ customLogLevel = levelStringToEnum[options.level];
+ }
+ if (logCallback === null) {
+ instance.userLogHandler = null;
+ } else {
+ instance.userLogHandler = (instance: Logger, level: LogLevel, ...args: unknown[]) => {
+ const message = args
+ .map(arg => {
+ if (arg == null) {
+ return null;
+ } else if (typeof arg === 'string') {
+ return arg;
+ } else if (typeof arg === 'number' || typeof arg === 'boolean') {
+ return arg.toString();
+ } else if (arg instanceof Error) {
+ return arg.message;
+ } else {
+ try {
+ return JSON.stringify(arg);
+ } catch (ignored) {
+ return null;
+ }
+ }
+ })
+ .filter(arg => arg)
+ .join(' ');
+ if (level >= (customLogLevel ?? instance.logLevel)) {
+ logCallback({
+ level: LogLevel[level].toLowerCase() as LogLevelString,
+ message,
+ args,
+ type: instance.name,
+ });
+ }
+ };
+ }
+ }
+}
+
+export const logger = new Logger('@firebase/vertexai');
diff --git a/packages/vertexai/lib/methods/chat-session-helpers.ts b/packages/vertexai/lib/methods/chat-session-helpers.ts
new file mode 100644
index 0000000000..4b9bb56db0
--- /dev/null
+++ b/packages/vertexai/lib/methods/chat-session-helpers.ts
@@ -0,0 +1,116 @@
+/**
+ * @license
+ * Copyright 2024 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { Content, POSSIBLE_ROLES, Part, Role, VertexAIErrorCode } from '../types';
+import { VertexAIError } from '../errors';
+
+// https://ai.google.dev/api/rest/v1beta/Content#part
+
+const VALID_PART_FIELDS: Array = [
+ 'text',
+ 'inlineData',
+ 'functionCall',
+ 'functionResponse',
+];
+
+const VALID_PARTS_PER_ROLE: { [key in Role]: Array } = {
+ user: ['text', 'inlineData'],
+ function: ['functionResponse'],
+ model: ['text', 'functionCall'],
+ // System instructions shouldn't be in history anyway.
+ system: ['text'],
+};
+
+const VALID_PREVIOUS_CONTENT_ROLES: { [key in Role]: Role[] } = {
+ user: ['model'],
+ function: ['model'],
+ model: ['user', 'function'],
+ // System instructions shouldn't be in history.
+ system: [],
+};
+
+export function validateChatHistory(history: Content[]): void {
+ let prevContent: Content | null = null;
+ for (const currContent of history) {
+ const { role, parts } = currContent;
+ if (!prevContent && role !== 'user') {
+ throw new VertexAIError(
+ VertexAIErrorCode.INVALID_CONTENT,
+ `First Content should be with role 'user', got ${role}`,
+ );
+ }
+ if (!POSSIBLE_ROLES.includes(role)) {
+ throw new VertexAIError(
+ VertexAIErrorCode.INVALID_CONTENT,
+ `Each item should include role field. Got ${role} but valid roles are: ${JSON.stringify(
+ POSSIBLE_ROLES,
+ )}`,
+ );
+ }
+
+ if (!Array.isArray(parts)) {
+ throw new VertexAIError(
+ VertexAIErrorCode.INVALID_CONTENT,
+ `Content should have 'parts' but property with an array of Parts`,
+ );
+ }
+
+ if (parts.length === 0) {
+ throw new VertexAIError(
+ VertexAIErrorCode.INVALID_CONTENT,
+ `Each Content should have at least one part`,
+ );
+ }
+
+ const countFields: Record = {
+ text: 0,
+ inlineData: 0,
+ functionCall: 0,
+ functionResponse: 0,
+ };
+
+ for (const part of parts) {
+ for (const key of VALID_PART_FIELDS) {
+ if (key in part) {
+ countFields[key] += 1;
+ }
+ }
+ }
+ const validParts = VALID_PARTS_PER_ROLE[role];
+ for (const key of VALID_PART_FIELDS) {
+ if (!validParts.includes(key) && countFields[key] > 0) {
+ throw new VertexAIError(
+ VertexAIErrorCode.INVALID_CONTENT,
+ `Content with role '${role}' can't contain '${key}' part`,
+ );
+ }
+ }
+
+ if (prevContent) {
+ const validPreviousContentRoles = VALID_PREVIOUS_CONTENT_ROLES[role];
+ if (!validPreviousContentRoles.includes(prevContent.role)) {
+ throw new VertexAIError(
+ VertexAIErrorCode.INVALID_CONTENT,
+ `Content with role '${role} can't follow '${
+ prevContent.role
+ }'. Valid previous roles: ${JSON.stringify(VALID_PREVIOUS_CONTENT_ROLES)}`,
+ );
+ }
+ }
+ prevContent = currContent;
+ }
+}
diff --git a/packages/vertexai/lib/methods/chat-session.ts b/packages/vertexai/lib/methods/chat-session.ts
new file mode 100644
index 0000000000..d22393d5b7
--- /dev/null
+++ b/packages/vertexai/lib/methods/chat-session.ts
@@ -0,0 +1,182 @@
+/**
+ * @license
+ * Copyright 2024 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {
+ Content,
+ GenerateContentRequest,
+ GenerateContentResult,
+ GenerateContentStreamResult,
+ Part,
+ RequestOptions,
+ StartChatParams,
+} from '../types';
+import { formatNewContent } from '../requests/request-helpers';
+import { formatBlockErrorMessage } from '../requests/response-helpers';
+import { validateChatHistory } from './chat-session-helpers';
+import { generateContent, generateContentStream } from './generate-content';
+import { ApiSettings } from '../types/internal';
+import { logger } from '../logger';
+
+/**
+ * Do not log a message for this error.
+ */
+const SILENT_ERROR = 'SILENT_ERROR';
+
+/**
+ * ChatSession class that enables sending chat messages and stores
+ * history of sent and received messages so far.
+ *
+ * @public
+ */
+export class ChatSession {
+ private _apiSettings: ApiSettings;
+ private _history: Content[] = [];
+ private _sendPromise: Promise = Promise.resolve();
+
+ constructor(
+ apiSettings: ApiSettings,
+ public model: string,
+ public params?: StartChatParams,
+ public requestOptions?: RequestOptions,
+ ) {
+ this._apiSettings = apiSettings;
+ if (params?.history) {
+ validateChatHistory(params.history);
+ this._history = params.history;
+ }
+ }
+
+ /**
+ * Gets the chat history so far. Blocked prompts are not added to history.
+ * Neither blocked candidates nor the prompts that generated them are added
+ * to history.
+ */
+ async getHistory(): Promise {
+ await this._sendPromise;
+ return this._history;
+ }
+
+ /**
+ * Sends a chat message and receives a non-streaming
+ * {@link GenerateContentResult}
+ */
+ async sendMessage(request: string | Array): Promise {
+ await this._sendPromise;
+ const newContent = formatNewContent(request);
+ const generateContentRequest: GenerateContentRequest = {
+ safetySettings: this.params?.safetySettings,
+ generationConfig: this.params?.generationConfig,
+ tools: this.params?.tools,
+ toolConfig: this.params?.toolConfig,
+ systemInstruction: this.params?.systemInstruction,
+ contents: [...this._history, newContent],
+ };
+ let finalResult = {} as GenerateContentResult;
+ // Add onto the chain.
+ this._sendPromise = this._sendPromise
+ .then(() =>
+ generateContent(this._apiSettings, this.model, generateContentRequest, this.requestOptions),
+ )
+ .then(result => {
+ if (result.response.candidates && result.response.candidates.length > 0) {
+ this._history.push(newContent);
+ const responseContent: Content = {
+ parts: result.response.candidates?.[0].content.parts || [],
+ // Response seems to come back without a role set.
+ role: result.response.candidates?.[0].content.role || 'model',
+ };
+ this._history.push(responseContent);
+ } else {
+ const blockErrorMessage = formatBlockErrorMessage(result.response);
+ if (blockErrorMessage) {
+ logger.warn(
+ `sendMessage() was unsuccessful. ${blockErrorMessage}. Inspect response object for details.`,
+ );
+ }
+ }
+ finalResult = result;
+ });
+ await this._sendPromise;
+ return finalResult;
+ }
+
+ /**
+ * Sends a chat message and receives the response as a
+ * {@link GenerateContentStreamResult}
containing an iterable stream
+ * and a response promise.
+ */
+ async sendMessageStream(
+ request: string | Array,
+ ): Promise {
+ await this._sendPromise;
+ const newContent = formatNewContent(request);
+ const generateContentRequest: GenerateContentRequest = {
+ safetySettings: this.params?.safetySettings,
+ generationConfig: this.params?.generationConfig,
+ tools: this.params?.tools,
+ toolConfig: this.params?.toolConfig,
+ systemInstruction: this.params?.systemInstruction,
+ contents: [...this._history, newContent],
+ };
+ const streamPromise = generateContentStream(
+ this._apiSettings,
+ this.model,
+ generateContentRequest,
+ this.requestOptions,
+ );
+
+ // Add onto the chain.
+ this._sendPromise = this._sendPromise
+ .then(() => streamPromise)
+ // This must be handled to avoid unhandled rejection, but jump
+ // to the final catch block with a label to not log this error.
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
+ .catch(_ignored => {
+ throw new Error(SILENT_ERROR);
+ })
+ .then(streamResult => streamResult.response)
+ .then(response => {
+ if (response.candidates && response.candidates.length > 0) {
+ this._history.push(newContent);
+ const responseContent = { ...response.candidates[0].content };
+ // Response seems to come back without a role set.
+ if (!responseContent.role) {
+ responseContent.role = 'model';
+ }
+ this._history.push(responseContent);
+ } else {
+ const blockErrorMessage = formatBlockErrorMessage(response);
+ if (blockErrorMessage) {
+ logger.warn(
+ `sendMessageStream() was unsuccessful. ${blockErrorMessage}. Inspect response object for details.`,
+ );
+ }
+ }
+ })
+ .catch(e => {
+ // Errors in streamPromise are already catchable by the user as
+ // streamPromise is returned.
+ // Avoid duplicating the error message in logs.
+ if (e.message !== SILENT_ERROR) {
+ // Users do not have access to _sendPromise to catch errors
+ // downstream from streamPromise, so they should not throw.
+ logger.error(e);
+ }
+ });
+ return streamPromise;
+ }
+}
diff --git a/packages/vertexai/lib/methods/count-tokens.ts b/packages/vertexai/lib/methods/count-tokens.ts
new file mode 100644
index 0000000000..10d41cffa8
--- /dev/null
+++ b/packages/vertexai/lib/methods/count-tokens.ts
@@ -0,0 +1,37 @@
+/**
+ * @license
+ * Copyright 2024 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { CountTokensRequest, CountTokensResponse, RequestOptions } from '../types';
+import { Task, makeRequest } from '../requests/request';
+import { ApiSettings } from '../types/internal';
+
+export async function countTokens(
+ apiSettings: ApiSettings,
+ model: string,
+ params: CountTokensRequest,
+ requestOptions?: RequestOptions,
+): Promise {
+ const response = await makeRequest(
+ model,
+ Task.COUNT_TOKENS,
+ apiSettings,
+ false,
+ JSON.stringify(params),
+ requestOptions,
+ );
+ return response.json();
+}
diff --git a/packages/vertexai/lib/methods/generate-content.ts b/packages/vertexai/lib/methods/generate-content.ts
new file mode 100644
index 0000000000..6d1a6ecb27
--- /dev/null
+++ b/packages/vertexai/lib/methods/generate-content.ts
@@ -0,0 +1,66 @@
+/**
+ * @license
+ * Copyright 2024 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {
+ GenerateContentRequest,
+ GenerateContentResponse,
+ GenerateContentResult,
+ GenerateContentStreamResult,
+ RequestOptions,
+} from '../types';
+import { Task, makeRequest } from '../requests/request';
+import { createEnhancedContentResponse } from '../requests/response-helpers';
+import { processStream } from '../requests/stream-reader';
+import { ApiSettings } from '../types/internal';
+
+export async function generateContentStream(
+ apiSettings: ApiSettings,
+ model: string,
+ params: GenerateContentRequest,
+ requestOptions?: RequestOptions,
+): Promise {
+ const response = await makeRequest(
+ model,
+ Task.STREAM_GENERATE_CONTENT,
+ apiSettings,
+ /* stream */ true,
+ JSON.stringify(params),
+ requestOptions,
+ );
+ return processStream(response);
+}
+
+export async function generateContent(
+ apiSettings: ApiSettings,
+ model: string,
+ params: GenerateContentRequest,
+ requestOptions?: RequestOptions,
+): Promise {
+ const response = await makeRequest(
+ model,
+ Task.GENERATE_CONTENT,
+ apiSettings,
+ /* stream */ false,
+ JSON.stringify(params),
+ requestOptions,
+ );
+ const responseJson: GenerateContentResponse = await response.json();
+ const enhancedResponse = createEnhancedContentResponse(responseJson);
+ return {
+ response: enhancedResponse,
+ };
+}
diff --git a/packages/vertexai/lib/models/generative-model.ts b/packages/vertexai/lib/models/generative-model.ts
new file mode 100644
index 0000000000..9df5d1c4ed
--- /dev/null
+++ b/packages/vertexai/lib/models/generative-model.ts
@@ -0,0 +1,179 @@
+/**
+ * @license
+ * Copyright 2024 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { generateContent, generateContentStream } from '../methods/generate-content';
+import {
+ Content,
+ CountTokensRequest,
+ CountTokensResponse,
+ GenerateContentRequest,
+ GenerateContentResult,
+ GenerateContentStreamResult,
+ GenerationConfig,
+ ModelParams,
+ Part,
+ RequestOptions,
+ SafetySetting,
+ StartChatParams,
+ Tool,
+ ToolConfig,
+ VertexAIErrorCode,
+} from '../types';
+import { VertexAIError } from '../errors';
+import { ChatSession } from '../methods/chat-session';
+import { countTokens } from '../methods/count-tokens';
+import { formatGenerateContentInput, formatSystemInstruction } from '../requests/request-helpers';
+import { VertexAI } from '../public-types';
+import { ApiSettings } from '../types/internal';
+import { VertexAIService } from '../service';
+
+/**
+ * Class for generative model APIs.
+ * @public
+ */
+export class GenerativeModel {
+ private _apiSettings: ApiSettings;
+ model: string;
+ generationConfig: GenerationConfig;
+ safetySettings: SafetySetting[];
+ requestOptions?: RequestOptions;
+ tools?: Tool[];
+ toolConfig?: ToolConfig;
+ systemInstruction?: Content;
+
+ constructor(vertexAI: VertexAI, modelParams: ModelParams, requestOptions?: RequestOptions) {
+ if (!vertexAI.app?.options?.apiKey) {
+ throw new VertexAIError(
+ VertexAIErrorCode.NO_API_KEY,
+ `The "apiKey" field is empty in the local Firebase config. Firebase VertexAI requires this field to contain a valid API key.`,
+ );
+ } else if (!vertexAI.app?.options?.projectId) {
+ throw new VertexAIError(
+ VertexAIErrorCode.NO_PROJECT_ID,
+ `The "projectId" field is empty in the local Firebase config. Firebase VertexAI requires this field to contain a valid project ID.`,
+ );
+ } else {
+ this._apiSettings = {
+ apiKey: vertexAI.app.options.apiKey,
+ project: vertexAI.app.options.projectId,
+ location: vertexAI.location,
+ };
+ if ((vertexAI as VertexAIService).appCheck) {
+ this._apiSettings.getAppCheckToken = () =>
+ (vertexAI as VertexAIService).appCheck!.getToken();
+ }
+
+ if ((vertexAI as VertexAIService).auth) {
+ this._apiSettings.getAuthToken = () => (vertexAI as VertexAIService).auth!.getToken();
+ }
+ }
+ if (modelParams.model.includes('/')) {
+ if (modelParams.model.startsWith('models/')) {
+ // Add "publishers/google" if the user is only passing in 'models/model-name'.
+ this.model = `publishers/google/${modelParams.model}`;
+ } else {
+ // Any other custom format (e.g. tuned models) must be passed in correctly.
+ this.model = modelParams.model;
+ }
+ } else {
+ // If path is not included, assume it's a non-tuned model.
+ this.model = `publishers/google/models/${modelParams.model}`;
+ }
+ this.generationConfig = modelParams.generationConfig || {};
+ this.safetySettings = modelParams.safetySettings || [];
+ this.tools = modelParams.tools;
+ this.toolConfig = modelParams.toolConfig;
+ this.systemInstruction = formatSystemInstruction(modelParams.systemInstruction);
+ this.requestOptions = requestOptions || {};
+ }
+
+ /**
+ * Makes a single non-streaming call to the model
+ * and returns an object containing a single {@link GenerateContentResponse}
.
+ */
+ async generateContent(
+ request: GenerateContentRequest | string | Array,
+ ): Promise {
+ const formattedParams = formatGenerateContentInput(request);
+ return generateContent(
+ this._apiSettings,
+ this.model,
+ {
+ generationConfig: this.generationConfig,
+ safetySettings: this.safetySettings,
+ tools: this.tools,
+ toolConfig: this.toolConfig,
+ systemInstruction: this.systemInstruction,
+ ...formattedParams,
+ },
+ this.requestOptions,
+ );
+ }
+
+ /**
+ * Makes a single streaming call to the model
+ * and returns an object containing an iterable stream that iterates
+ * over all chunks in the streaming response as well as
+ * a promise that returns the final aggregated response.
+ */
+ async generateContentStream(
+ request: GenerateContentRequest | string | Array,
+ ): Promise {
+ const formattedParams = formatGenerateContentInput(request);
+ return generateContentStream(
+ this._apiSettings,
+ this.model,
+ {
+ generationConfig: this.generationConfig,
+ safetySettings: this.safetySettings,
+ tools: this.tools,
+ toolConfig: this.toolConfig,
+ systemInstruction: this.systemInstruction,
+ ...formattedParams,
+ },
+ this.requestOptions,
+ );
+ }
+
+ /**
+ * Gets a new {@link ChatSession}
instance which can be used for
+ * multi-turn chats.
+ */
+ startChat(startChatParams?: StartChatParams): ChatSession {
+ return new ChatSession(
+ this._apiSettings,
+ this.model,
+ {
+ tools: this.tools,
+ toolConfig: this.toolConfig,
+ systemInstruction: this.systemInstruction,
+ ...startChatParams,
+ },
+ this.requestOptions,
+ );
+ }
+
+ /**
+ * Counts the tokens in the provided request.
+ */
+ async countTokens(
+ request: CountTokensRequest | string | Array,
+ ): Promise {
+ const formattedParams = formatGenerateContentInput(request);
+ return countTokens(this._apiSettings, this.model, formattedParams);
+ }
+}
diff --git a/packages/vertexai/lib/public-types.ts b/packages/vertexai/lib/public-types.ts
new file mode 100644
index 0000000000..280fee9d1c
--- /dev/null
+++ b/packages/vertexai/lib/public-types.ts
@@ -0,0 +1,40 @@
+/**
+ * @license
+ * Copyright 2024 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { FirebaseApp } from '@firebase/app';
+
+export * from './types';
+
+/**
+ * An instance of the Vertex AI in Firebase SDK.
+ * @public
+ */
+export interface VertexAI {
+ /**
+ * The {@link @firebase/app#FirebaseApp} this {@link VertexAI}
instance is associated with.
+ */
+ app: FirebaseApp;
+ location: string;
+}
+
+/**
+ * Options when initializing the Vertex AI in Firebase SDK.
+ * @public
+ */
+export interface VertexAIOptions {
+ location?: string;
+}
diff --git a/packages/vertexai/lib/requests/request-helpers.ts b/packages/vertexai/lib/requests/request-helpers.ts
new file mode 100644
index 0000000000..44405cb6f4
--- /dev/null
+++ b/packages/vertexai/lib/requests/request-helpers.ts
@@ -0,0 +1,115 @@
+/**
+ * @license
+ * Copyright 2024 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { Content, GenerateContentRequest, Part, VertexAIErrorCode } from '../types';
+import { VertexAIError } from '../errors';
+
+export function formatSystemInstruction(input?: string | Part | Content): Content | undefined {
+ // null or undefined
+ if (input == null) {
+ return undefined;
+ } else if (typeof input === 'string') {
+ return { role: 'system', parts: [{ text: input }] } as Content;
+ } else if ((input as Part).text) {
+ return { role: 'system', parts: [input as Part] };
+ } else if ((input as Content).parts) {
+ if (!(input as Content).role) {
+ return { role: 'system', parts: (input as Content).parts };
+ } else {
+ return input as Content;
+ }
+ }
+}
+
+export function formatNewContent(request: string | Array): Content {
+ let newParts: Part[] = [];
+ if (typeof request === 'string') {
+ newParts = [{ text: request }];
+ } else {
+ for (const partOrString of request) {
+ if (typeof partOrString === 'string') {
+ newParts.push({ text: partOrString });
+ } else {
+ newParts.push(partOrString);
+ }
+ }
+ }
+ return assignRoleToPartsAndValidateSendMessageRequest(newParts);
+}
+
+/**
+ * When multiple Part types (i.e. FunctionResponsePart and TextPart) are
+ * passed in a single Part array, we may need to assign different roles to each
+ * part. Currently only FunctionResponsePart requires a role other than 'user'.
+ * @private
+ * @param parts Array of parts to pass to the model
+ * @returns Array of content items
+ */
+function assignRoleToPartsAndValidateSendMessageRequest(parts: Part[]): Content {
+ const userContent: Content = { role: 'user', parts: [] };
+ const functionContent: Content = { role: 'function', parts: [] };
+ let hasUserContent = false;
+ let hasFunctionContent = false;
+ for (const part of parts) {
+ if ('functionResponse' in part) {
+ functionContent.parts.push(part);
+ hasFunctionContent = true;
+ } else {
+ userContent.parts.push(part);
+ hasUserContent = true;
+ }
+ }
+
+ if (hasUserContent && hasFunctionContent) {
+ throw new VertexAIError(
+ VertexAIErrorCode.INVALID_CONTENT,
+ 'Within a single message, FunctionResponse cannot be mixed with other type of Part in the request for sending chat message.',
+ );
+ }
+
+ if (!hasUserContent && !hasFunctionContent) {
+ throw new VertexAIError(
+ VertexAIErrorCode.INVALID_CONTENT,
+ 'No Content is provided for sending chat message.',
+ );
+ }
+
+ if (hasUserContent) {
+ return userContent;
+ }
+
+ return functionContent;
+}
+
+export function formatGenerateContentInput(
+ params: GenerateContentRequest | string | Array,
+): GenerateContentRequest {
+ let formattedRequest: GenerateContentRequest;
+ if ((params as GenerateContentRequest).contents) {
+ formattedRequest = params as GenerateContentRequest;
+ } else {
+ // Array or string
+ const content = formatNewContent(params as string | Array);
+ formattedRequest = { contents: [content] };
+ }
+ if ((params as GenerateContentRequest).systemInstruction) {
+ formattedRequest.systemInstruction = formatSystemInstruction(
+ (params as GenerateContentRequest).systemInstruction,
+ );
+ }
+ return formattedRequest;
+}
diff --git a/packages/vertexai/lib/requests/request.ts b/packages/vertexai/lib/requests/request.ts
new file mode 100644
index 0000000000..f81b40635e
--- /dev/null
+++ b/packages/vertexai/lib/requests/request.ts
@@ -0,0 +1,230 @@
+/**
+ * @license
+ * Copyright 2024 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { ErrorDetails, RequestOptions, VertexAIErrorCode } from '../types';
+import { VertexAIError } from '../errors';
+import { ApiSettings } from '../types/internal';
+import {
+ DEFAULT_API_VERSION,
+ DEFAULT_BASE_URL,
+ DEFAULT_FETCH_TIMEOUT_MS,
+ LANGUAGE_TAG,
+ PACKAGE_VERSION
+} from '../constants';
+import { logger } from '../logger';
+
+export enum Task {
+ GENERATE_CONTENT = 'generateContent',
+ STREAM_GENERATE_CONTENT = 'streamGenerateContent',
+ COUNT_TOKENS = 'countTokens'
+}
+
+export class RequestUrl {
+ constructor(
+ public model: string,
+ public task: Task,
+ public apiSettings: ApiSettings,
+ public stream: boolean,
+ public requestOptions?: RequestOptions
+ ) {}
+ toString(): string {
+ // TODO: allow user-set option if that feature becomes available
+ const apiVersion = DEFAULT_API_VERSION;
+ const baseUrl = this.requestOptions?.baseUrl || DEFAULT_BASE_URL;
+ let url = `${baseUrl}/${apiVersion}`;
+ url += `/projects/${this.apiSettings.project}`;
+ url += `/locations/${this.apiSettings.location}`;
+ url += `/${this.model}`;
+ url += `:${this.task}`;
+ if (this.stream) {
+ url += '?alt=sse';
+ }
+ return url;
+ }
+
+ /**
+ * If the model needs to be passed to the backend, it needs to
+ * include project and location path.
+ */
+ get fullModelString(): string {
+ let modelString = `projects/${this.apiSettings.project}`;
+ modelString += `/locations/${this.apiSettings.location}`;
+ modelString += `/${this.model}`;
+ return modelString;
+ }
+}
+
+/**
+ * Log language and "fire/version" to x-goog-api-client
+ */
+function getClientHeaders(): string {
+ const loggingTags = [];
+ loggingTags.push(`${LANGUAGE_TAG}/${PACKAGE_VERSION}`);
+ loggingTags.push(`fire/${PACKAGE_VERSION}`);
+ return loggingTags.join(' ');
+}
+
+export async function getHeaders(url: RequestUrl): Promise {
+ const headers = new Headers();
+ headers.append('Content-Type', 'application/json');
+ headers.append('x-goog-api-client', getClientHeaders());
+ headers.append('x-goog-api-key', url.apiSettings.apiKey);
+ if (url.apiSettings.getAppCheckToken) {
+ const appCheckToken = await url.apiSettings.getAppCheckToken();
+ if (appCheckToken) {
+ headers.append('X-Firebase-AppCheck', appCheckToken.token);
+ if (appCheckToken.error) {
+ logger.warn(
+ `Unable to obtain a valid App Check token: ${appCheckToken.error.message}`
+ );
+ }
+ }
+ }
+
+ if (url.apiSettings.getAuthToken) {
+ const authToken = await url.apiSettings.getAuthToken();
+ if (authToken) {
+ headers.append('Authorization', `Firebase ${authToken.accessToken}`);
+ }
+ }
+
+ return headers;
+}
+
+export async function constructRequest(
+ model: string,
+ task: Task,
+ apiSettings: ApiSettings,
+ stream: boolean,
+ body: string,
+ requestOptions?: RequestOptions
+): Promise<{ url: string; fetchOptions: RequestInit }> {
+ const url = new RequestUrl(model, task, apiSettings, stream, requestOptions);
+ return {
+ url: url.toString(),
+ fetchOptions: {
+ method: 'POST',
+ headers: await getHeaders(url),
+ body
+ }
+ };
+}
+
+export async function makeRequest(
+ model: string,
+ task: Task,
+ apiSettings: ApiSettings,
+ stream: boolean,
+ body: string,
+ requestOptions?: RequestOptions
+): Promise {
+ const url = new RequestUrl(model, task, apiSettings, stream, requestOptions);
+ let response;
+ let fetchTimeoutId: string | number | NodeJS.Timeout | undefined;
+ try {
+ const request = await constructRequest(
+ model,
+ task,
+ apiSettings,
+ stream,
+ body,
+ requestOptions
+ );
+ // Timeout is 180s by default
+ const timeoutMillis =
+ requestOptions?.timeout != null && requestOptions.timeout >= 0
+ ? requestOptions.timeout
+ : DEFAULT_FETCH_TIMEOUT_MS;
+ const abortController = new AbortController();
+ fetchTimeoutId = setTimeout(() => abortController.abort(), timeoutMillis);
+ request.fetchOptions.signal = abortController.signal;
+
+ response = await fetch(request.url, request.fetchOptions);
+ if (!response.ok) {
+ let message = '';
+ let errorDetails;
+ try {
+ const json = await response.json();
+ message = json.error.message;
+ if (json.error.details) {
+ message += ` ${JSON.stringify(json.error.details)}`;
+ errorDetails = json.error.details;
+ }
+ } catch (e) {
+ // ignored
+ }
+ if (
+ response.status === 403 &&
+ errorDetails.some(
+ (detail: ErrorDetails) => detail.reason === 'SERVICE_DISABLED'
+ ) &&
+ errorDetails.some((detail: ErrorDetails) =>
+ (
+ detail.links as Array>
+ )?.[0]?.description.includes(
+ 'Google developers console API activation'
+ )
+ )
+ ) {
+ throw new VertexAIError(
+ VertexAIErrorCode.API_NOT_ENABLED,
+ `The Vertex AI in Firebase SDK requires the Vertex AI in Firebase ` +
+ `API ('firebasevertexai.googleapis.com') to be enabled in your ` +
+ `Firebase project. Enable this API by visiting the Firebase Console ` +
+ `at https://console.firebase.google.com/project/${url.apiSettings.project}/genai/ ` +
+ `and clicking "Get started". If you enabled this API recently, ` +
+ `wait a few minutes for the action to propagate to our systems and ` +
+ `then retry.`,
+ {
+ status: response.status,
+ statusText: response.statusText,
+ errorDetails
+ }
+ );
+ }
+ throw new VertexAIError(
+ VertexAIErrorCode.FETCH_ERROR,
+ `Error fetching from ${url}: [${response.status} ${response.statusText}] ${message}`,
+ {
+ status: response.status,
+ statusText: response.statusText,
+ errorDetails
+ }
+ );
+ }
+ } catch (e) {
+ let err = e as Error;
+ if (
+ (e as VertexAIError).code !== VertexAIErrorCode.FETCH_ERROR &&
+ (e as VertexAIError).code !== VertexAIErrorCode.API_NOT_ENABLED &&
+ e instanceof Error
+ ) {
+ err = new VertexAIError(
+ VertexAIErrorCode.ERROR,
+ `Error fetching from ${url.toString()}: ${e.message}`
+ );
+ err.stack = e.stack;
+ }
+
+ throw err;
+ } finally {
+ if (fetchTimeoutId) {
+ clearTimeout(fetchTimeoutId);
+ }
+ }
+ return response;
+}
diff --git a/packages/vertexai/lib/requests/response-helpers.ts b/packages/vertexai/lib/requests/response-helpers.ts
new file mode 100644
index 0000000000..27347d10f0
--- /dev/null
+++ b/packages/vertexai/lib/requests/response-helpers.ts
@@ -0,0 +1,198 @@
+/**
+ * @license
+ * Copyright 2024 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {
+ EnhancedGenerateContentResponse,
+ FinishReason,
+ FunctionCall,
+ GenerateContentCandidate,
+ GenerateContentResponse,
+ VertexAIErrorCode
+} from '../types';
+import { VertexAIError } from '../errors';
+import { logger } from '../logger';
+
+/**
+ * Creates an EnhancedGenerateContentResponse object that has helper functions and
+ * other modifications that improve usability.
+ */
+export function createEnhancedContentResponse(
+ response: GenerateContentResponse
+): EnhancedGenerateContentResponse {
+ /**
+ * The Vertex AI backend omits default values.
+ * This causes the `index` property to be omitted from the first candidate in the
+ * response, since it has index 0, and 0 is a default value.
+ * See: https://github.com/firebase/firebase-js-sdk/issues/8566
+ */
+ if (response.candidates && !response.candidates[0].hasOwnProperty('index')) {
+ response.candidates[0].index = 0;
+ }
+
+ const responseWithHelpers = addHelpers(response);
+ return responseWithHelpers;
+}
+
+/**
+ * Adds convenience helper methods to a response object, including stream
+ * chunks (as long as each chunk is a complete GenerateContentResponse JSON).
+ */
+export function addHelpers(
+ response: GenerateContentResponse
+): EnhancedGenerateContentResponse {
+ (response as EnhancedGenerateContentResponse).text = () => {
+ if (response.candidates && response.candidates.length > 0) {
+ if (response.candidates.length > 1) {
+ logger.warn(
+ `This response had ${response.candidates.length} ` +
+ `candidates. Returning text from the first candidate only. ` +
+ `Access response.candidates directly to use the other candidates.`
+ );
+ }
+ if (hadBadFinishReason(response.candidates[0])) {
+ throw new VertexAIError(
+ VertexAIErrorCode.RESPONSE_ERROR,
+ `Response error: ${formatBlockErrorMessage(
+ response
+ )}. Response body stored in error.response`,
+ {
+ response
+ }
+ );
+ }
+ return getText(response);
+ } else if (response.promptFeedback) {
+ throw new VertexAIError(
+ VertexAIErrorCode.RESPONSE_ERROR,
+ `Text not available. ${formatBlockErrorMessage(response)}`,
+ {
+ response
+ }
+ );
+ }
+ return '';
+ };
+ (response as EnhancedGenerateContentResponse).functionCalls = () => {
+ if (response.candidates && response.candidates.length > 0) {
+ if (response.candidates.length > 1) {
+ logger.warn(
+ `This response had ${response.candidates.length} ` +
+ `candidates. Returning function calls from the first candidate only. ` +
+ `Access response.candidates directly to use the other candidates.`
+ );
+ }
+ if (hadBadFinishReason(response.candidates[0])) {
+ throw new VertexAIError(
+ VertexAIErrorCode.RESPONSE_ERROR,
+ `Response error: ${formatBlockErrorMessage(
+ response
+ )}. Response body stored in error.response`,
+ {
+ response
+ }
+ );
+ }
+ return getFunctionCalls(response);
+ } else if (response.promptFeedback) {
+ throw new VertexAIError(
+ VertexAIErrorCode.RESPONSE_ERROR,
+ `Function call not available. ${formatBlockErrorMessage(response)}`,
+ {
+ response
+ }
+ );
+ }
+ return undefined;
+ };
+ return response as EnhancedGenerateContentResponse;
+}
+
+/**
+ * Returns all text found in all parts of first candidate.
+ */
+export function getText(response: GenerateContentResponse): string {
+ const textStrings = [];
+ if (response.candidates?.[0].content?.parts) {
+ for (const part of response.candidates?.[0].content?.parts) {
+ if (part.text) {
+ textStrings.push(part.text);
+ }
+ }
+ }
+ if (textStrings.length > 0) {
+ return textStrings.join('');
+ } else {
+ return '';
+ }
+}
+
+/**
+ * Returns {@link FunctionCall}
s associated with first candidate.
+ */
+export function getFunctionCalls(
+ response: GenerateContentResponse
+): FunctionCall[] | undefined {
+ const functionCalls: FunctionCall[] = [];
+ if (response.candidates?.[0].content?.parts) {
+ for (const part of response.candidates?.[0].content?.parts) {
+ if (part.functionCall) {
+ functionCalls.push(part.functionCall);
+ }
+ }
+ }
+ if (functionCalls.length > 0) {
+ return functionCalls;
+ } else {
+ return undefined;
+ }
+}
+
+const badFinishReasons = [FinishReason.RECITATION, FinishReason.SAFETY];
+
+function hadBadFinishReason(candidate: GenerateContentCandidate): boolean {
+ return (
+ !!candidate.finishReason &&
+ badFinishReasons.includes(candidate.finishReason)
+ );
+}
+
+export function formatBlockErrorMessage(
+ response: GenerateContentResponse
+): string {
+ let message = '';
+ if (
+ (!response.candidates || response.candidates.length === 0) &&
+ response.promptFeedback
+ ) {
+ message += 'Response was blocked';
+ if (response.promptFeedback?.blockReason) {
+ message += ` due to ${response.promptFeedback.blockReason}`;
+ }
+ if (response.promptFeedback?.blockReasonMessage) {
+ message += `: ${response.promptFeedback.blockReasonMessage}`;
+ }
+ } else if (response.candidates?.[0]) {
+ const firstCandidate = response.candidates[0];
+ if (hadBadFinishReason(firstCandidate)) {
+ message += `Candidate was blocked due to ${firstCandidate.finishReason}`;
+ if (firstCandidate.finishMessage) {
+ message += `: ${firstCandidate.finishMessage}`;
+ }
+ }
+ }
+ return message;
+}
diff --git a/packages/vertexai/lib/requests/schema-builder.ts b/packages/vertexai/lib/requests/schema-builder.ts
new file mode 100644
index 0000000000..3d219d58b1
--- /dev/null
+++ b/packages/vertexai/lib/requests/schema-builder.ts
@@ -0,0 +1,292 @@
+/**
+ * @license
+ * Copyright 2024 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { VertexAIError } from '../errors';
+import { VertexAIErrorCode } from '../types';
+import {
+ SchemaInterface,
+ SchemaType,
+ SchemaParams,
+ SchemaRequest,
+ ObjectSchemaInterface
+} from '../types/schema';
+
+/**
+ * Parent class encompassing all Schema types, with static methods that
+ * allow building specific Schema types. This class can be converted with
+ * `JSON.stringify()` into a JSON string accepted by Vertex AI REST endpoints.
+ * (This string conversion is automatically done when calling SDK methods.)
+ * @public
+ */
+export abstract class Schema implements SchemaInterface {
+ /**
+ * Optional. The type of the property. {@link
+ * SchemaType}.
+ */
+ type: SchemaType;
+ /** Optional. The format of the property.
+ * Supported formats:
+ *
+ * - for NUMBER type: "float", "double"
+ * - for INTEGER type: "int32", "int64"
+ * - for STRING type: "email", "byte", etc
+ *
+ */
+ format?: string;
+ /** Optional. The description of the property. */
+ description?: string;
+ /** Optional. Whether the property is nullable. Defaults to false. */
+ nullable: boolean;
+ /** Optional. The example of the property. */
+ example?: unknown;
+ /**
+ * Allows user to add other schema properties that have not yet
+ * been officially added to the SDK.
+ */
+ [key: string]: unknown;
+
+ constructor(schemaParams: SchemaInterface) {
+ // eslint-disable-next-line guard-for-in
+ for (const paramKey in schemaParams) {
+ this[paramKey] = schemaParams[paramKey];
+ }
+ // Ensure these are explicitly set to avoid TS errors.
+ this.type = schemaParams.type;
+ this.nullable = schemaParams.hasOwnProperty('nullable')
+ ? !!schemaParams.nullable
+ : false;
+ }
+
+ /**
+ * Defines how this Schema should be serialized as JSON.
+ * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#tojson_behavior
+ * @internal
+ */
+ toJSON(): SchemaRequest {
+ const obj: { type: SchemaType; [key: string]: unknown } = {
+ type: this.type
+ };
+ for (const prop in this) {
+ if (this.hasOwnProperty(prop) && this[prop] !== undefined) {
+ if (prop !== 'required' || this.type === SchemaType.OBJECT) {
+ obj[prop] = this[prop];
+ }
+ }
+ }
+ return obj as SchemaRequest;
+ }
+
+ static array(arrayParams: SchemaParams & { items: Schema }): ArraySchema {
+ return new ArraySchema(arrayParams, arrayParams.items);
+ }
+
+ static object(
+ objectParams: SchemaParams & {
+ properties: {
+ [k: string]: Schema;
+ };
+ optionalProperties?: string[];
+ }
+ ): ObjectSchema {
+ return new ObjectSchema(
+ objectParams,
+ objectParams.properties,
+ objectParams.optionalProperties
+ );
+ }
+
+ // eslint-disable-next-line id-blacklist
+ static string(stringParams?: SchemaParams): StringSchema {
+ return new StringSchema(stringParams);
+ }
+
+ static enumString(
+ stringParams: SchemaParams & { enum: string[] }
+ ): StringSchema {
+ return new StringSchema(stringParams, stringParams.enum);
+ }
+
+ static integer(integerParams?: SchemaParams): IntegerSchema {
+ return new IntegerSchema(integerParams);
+ }
+
+ // eslint-disable-next-line id-blacklist
+ static number(numberParams?: SchemaParams): NumberSchema {
+ return new NumberSchema(numberParams);
+ }
+
+ // eslint-disable-next-line id-blacklist
+ static boolean(booleanParams?: SchemaParams): BooleanSchema {
+ return new BooleanSchema(booleanParams);
+ }
+}
+
+/**
+ * A type that includes all specific Schema types.
+ * @public
+ */
+export type TypedSchema =
+ | IntegerSchema
+ | NumberSchema
+ | StringSchema
+ | BooleanSchema
+ | ObjectSchema
+ | ArraySchema;
+
+/**
+ * Schema class for "integer" types.
+ * @public
+ */
+export class IntegerSchema extends Schema {
+ constructor(schemaParams?: SchemaParams) {
+ super({
+ type: SchemaType.INTEGER,
+ ...schemaParams
+ });
+ }
+}
+
+/**
+ * Schema class for "number" types.
+ * @public
+ */
+export class NumberSchema extends Schema {
+ constructor(schemaParams?: SchemaParams) {
+ super({
+ type: SchemaType.NUMBER,
+ ...schemaParams
+ });
+ }
+}
+
+/**
+ * Schema class for "boolean" types.
+ * @public
+ */
+export class BooleanSchema extends Schema {
+ constructor(schemaParams?: SchemaParams) {
+ super({
+ type: SchemaType.BOOLEAN,
+ ...schemaParams
+ });
+ }
+}
+
+/**
+ * Schema class for "string" types. Can be used with or without
+ * enum values.
+ * @public
+ */
+export class StringSchema extends Schema {
+ enum?: string[];
+ constructor(schemaParams?: SchemaParams, enumValues?: string[]) {
+ super({
+ type: SchemaType.STRING,
+ ...schemaParams
+ });
+ this.enum = enumValues;
+ }
+
+ /**
+ * @internal
+ */
+ toJSON(): SchemaRequest {
+ const obj = super.toJSON();
+ if (this.enum) {
+ obj['enum'] = this.enum;
+ }
+ return obj as SchemaRequest;
+ }
+}
+
+/**
+ * Schema class for "array" types.
+ * The `items` param should refer to the type of item that can be a member
+ * of the array.
+ * @public
+ */
+export class ArraySchema extends Schema {
+ constructor(schemaParams: SchemaParams, public items: TypedSchema) {
+ super({
+ type: SchemaType.ARRAY,
+ ...schemaParams
+ });
+ }
+
+ /**
+ * @internal
+ */
+ toJSON(): SchemaRequest {
+ const obj = super.toJSON();
+ obj.items = this.items.toJSON();
+ return obj;
+ }
+}
+
+/**
+ * Schema class for "object" types.
+ * The `properties` param must be a map of `Schema` objects.
+ * @public
+ */
+export class ObjectSchema extends Schema {
+ constructor(
+ schemaParams: SchemaParams,
+ public properties: {
+ [k: string]: TypedSchema;
+ },
+ public optionalProperties: string[] = []
+ ) {
+ super({
+ type: SchemaType.OBJECT,
+ ...schemaParams
+ });
+ }
+
+ /**
+ * @internal
+ */
+ toJSON(): SchemaRequest {
+ const obj = super.toJSON();
+ obj.properties = { ...this.properties };
+ const required = [];
+ if (this.optionalProperties) {
+ for (const propertyKey of this.optionalProperties) {
+ if (!this.properties.hasOwnProperty(propertyKey)) {
+ throw new VertexAIError(
+ VertexAIErrorCode.INVALID_SCHEMA,
+ `Property "${propertyKey}" specified in "optionalProperties" does not exist.`
+ );
+ }
+ }
+ }
+ for (const propertyKey in this.properties) {
+ if (this.properties.hasOwnProperty(propertyKey)) {
+ obj.properties[propertyKey] = this.properties[
+ propertyKey
+ ].toJSON() as SchemaRequest;
+ if (!this.optionalProperties.includes(propertyKey)) {
+ required.push(propertyKey);
+ }
+ }
+ }
+ if (required.length > 0) {
+ obj.required = required;
+ }
+ delete (obj as ObjectSchemaInterface).optionalProperties;
+ return obj as SchemaRequest;
+ }
+}
diff --git a/packages/vertexai/lib/requests/stream-reader.ts b/packages/vertexai/lib/requests/stream-reader.ts
new file mode 100644
index 0000000000..8162407d90
--- /dev/null
+++ b/packages/vertexai/lib/requests/stream-reader.ts
@@ -0,0 +1,205 @@
+/**
+ * @license
+ * Copyright 2024 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {
+ EnhancedGenerateContentResponse,
+ GenerateContentCandidate,
+ GenerateContentResponse,
+ GenerateContentStreamResult,
+ Part,
+ VertexAIErrorCode
+} from '../types';
+import { VertexAIError } from '../errors';
+import { createEnhancedContentResponse } from './response-helpers';
+
+const responseLineRE = /^data\: (.*)(?:\n\n|\r\r|\r\n\r\n)/;
+
+/**
+ * Process a response.body stream from the backend and return an
+ * iterator that provides one complete GenerateContentResponse at a time
+ * and a promise that resolves with a single aggregated
+ * GenerateContentResponse.
+ *
+ * @param response - Response from a fetch call
+ */
+export function processStream(response: Response): GenerateContentStreamResult {
+ const inputStream = response.body!.pipeThrough(
+ new TextDecoderStream('utf8', { fatal: true })
+ );
+ const responseStream =
+ getResponseStream(inputStream);
+ const [stream1, stream2] = responseStream.tee();
+ return {
+ stream: generateResponseSequence(stream1),
+ response: getResponsePromise(stream2)
+ };
+}
+
+async function getResponsePromise(
+ stream: ReadableStream
+): Promise {
+ const allResponses: GenerateContentResponse[] = [];
+ const reader = stream.getReader();
+ while (true) {
+ const { done, value } = await reader.read();
+ if (done) {
+ const enhancedResponse = createEnhancedContentResponse(
+ aggregateResponses(allResponses)
+ );
+ return enhancedResponse;
+ }
+ allResponses.push(value);
+ }
+}
+
+async function* generateResponseSequence(
+ stream: ReadableStream
+): AsyncGenerator {
+ const reader = stream.getReader();
+ while (true) {
+ const { value, done } = await reader.read();
+ if (done) {
+ break;
+ }
+
+ const enhancedResponse = createEnhancedContentResponse(value);
+ yield enhancedResponse;
+ }
+}
+
+/**
+ * Reads a raw stream from the fetch response and join incomplete
+ * chunks, returning a new stream that provides a single complete
+ * GenerateContentResponse in each iteration.
+ */
+export function getResponseStream(
+ inputStream: ReadableStream
+): ReadableStream {
+ const reader = inputStream.getReader();
+ const stream = new ReadableStream({
+ start(controller) {
+ let currentText = '';
+ return pump();
+ function pump(): Promise<(() => Promise) | undefined> {
+ return reader.read().then(({ value, done }) => {
+ if (done) {
+ if (currentText.trim()) {
+ controller.error(
+ new VertexAIError(
+ VertexAIErrorCode.PARSE_FAILED,
+ 'Failed to parse stream'
+ )
+ );
+ return;
+ }
+ controller.close();
+ return;
+ }
+
+ currentText += value;
+ let match = currentText.match(responseLineRE);
+ let parsedResponse: T;
+ while (match) {
+ try {
+ parsedResponse = JSON.parse(match[1]);
+ } catch (e) {
+ controller.error(
+ new VertexAIError(
+ VertexAIErrorCode.PARSE_FAILED,
+ `Error parsing JSON response: "${match[1]}`
+ )
+ );
+ return;
+ }
+ controller.enqueue(parsedResponse);
+ currentText = currentText.substring(match[0].length);
+ match = currentText.match(responseLineRE);
+ }
+ return pump();
+ });
+ }
+ }
+ });
+ return stream;
+}
+
+/**
+ * Aggregates an array of `GenerateContentResponse`s into a single
+ * GenerateContentResponse.
+ */
+export function aggregateResponses(
+ responses: GenerateContentResponse[]
+): GenerateContentResponse {
+ const lastResponse = responses[responses.length - 1];
+ const aggregatedResponse: GenerateContentResponse = {
+ promptFeedback: lastResponse?.promptFeedback
+ };
+ for (const response of responses) {
+ if (response.candidates) {
+ for (const candidate of response.candidates) {
+ // Index will be undefined if it's the first index (0), so we should use 0 if it's undefined.
+ // See: https://github.com/firebase/firebase-js-sdk/issues/8566
+ const i = candidate.index || 0;
+ if (!aggregatedResponse.candidates) {
+ aggregatedResponse.candidates = [];
+ }
+ if (!aggregatedResponse.candidates[i]) {
+ aggregatedResponse.candidates[i] = {
+ index: candidate.index
+ } as GenerateContentCandidate;
+ }
+ // Keep overwriting, the last one will be final
+ aggregatedResponse.candidates[i].citationMetadata =
+ candidate.citationMetadata;
+ aggregatedResponse.candidates[i].finishReason = candidate.finishReason;
+ aggregatedResponse.candidates[i].finishMessage =
+ candidate.finishMessage;
+ aggregatedResponse.candidates[i].safetyRatings =
+ candidate.safetyRatings;
+
+ /**
+ * Candidates should always have content and parts, but this handles
+ * possible malformed responses.
+ */
+ if (candidate.content && candidate.content.parts) {
+ if (!aggregatedResponse.candidates[i].content) {
+ aggregatedResponse.candidates[i].content = {
+ role: candidate.content.role || 'user',
+ parts: []
+ };
+ }
+ const newPart: Partial = {};
+ for (const part of candidate.content.parts) {
+ if (part.text) {
+ newPart.text = part.text;
+ }
+ if (part.functionCall) {
+ newPart.functionCall = part.functionCall;
+ }
+ if (Object.keys(newPart).length === 0) {
+ newPart.text = '';
+ }
+ aggregatedResponse.candidates[i].content.parts.push(
+ newPart as Part
+ );
+ }
+ }
+ }
+ }
+ }
+ return aggregatedResponse;
+}
diff --git a/packages/vertexai/lib/service.ts b/packages/vertexai/lib/service.ts
new file mode 100644
index 0000000000..1c1573a926
--- /dev/null
+++ b/packages/vertexai/lib/service.ts
@@ -0,0 +1,50 @@
+/**
+ * @license
+ * Copyright 2024 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { FirebaseApp } from '@firebase/app';
+import { VertexAI, VertexAIOptions } from './public-types';
+import {
+ AppCheckInternalComponentName,
+ FirebaseAppCheckInternal,
+} from '@firebase/app-check-interop-types';
+import { Provider } from '@firebase/component';
+import { FirebaseAuthInternal, FirebaseAuthInternalName } from '@firebase/auth-interop-types';
+import { DEFAULT_LOCATION } from './constants';
+import { _FirebaseService } from './types/internal';
+
+export class VertexAIService implements VertexAI, _FirebaseService {
+ auth: FirebaseAuthInternal | null;
+ appCheck: FirebaseAppCheckInternal | null;
+ location: string;
+
+ constructor(
+ public app: FirebaseApp,
+ authProvider?: Provider,
+ appCheckProvider?: Provider,
+ public options?: VertexAIOptions,
+ ) {
+ const appCheck = appCheckProvider?.getImmediate({ optional: true });
+ const auth = authProvider?.getImmediate({ optional: true });
+ this.auth = auth || null;
+ this.appCheck = appCheck || null;
+ this.location = this.options?.location || DEFAULT_LOCATION;
+ }
+
+ _delete(): Promise {
+ return Promise.resolve();
+ }
+}
diff --git a/packages/vertexai/lib/types/content.ts b/packages/vertexai/lib/types/content.ts
new file mode 100644
index 0000000000..316769856a
--- /dev/null
+++ b/packages/vertexai/lib/types/content.ts
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2016-present Invertase Limited & Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this library except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+import { Role } from './enums';
+
+/**
+ * Content type for both prompts and response candidates.
+ * @public
+ */
+export interface Content {
+ role: Role;
+ parts: Part[];
+}
+
+/**
+ * Content part - includes text, image/video, or function call/response
+ * part types.
+ * @public
+ */
+export type Part =
+ | TextPart
+ | InlineDataPart
+ | FunctionCallPart
+ | FunctionResponsePart
+ | FileDataPart;
+
+/**
+ * Content part interface if the part represents a text string.
+ * @public
+ */
+export interface TextPart {
+ text: string;
+ inlineData?: never;
+ functionCall?: never;
+ functionResponse?: never;
+}
+
+/**
+ * Content part interface if the part represents an image.
+ * @public
+ */
+export interface InlineDataPart {
+ text?: never;
+ inlineData: GenerativeContentBlob;
+ functionCall?: never;
+ functionResponse?: never;
+ /**
+ * Applicable if `inlineData` is a video.
+ */
+ videoMetadata?: VideoMetadata;
+}
+
+/**
+ * Describes the input video content.
+ * @public
+ */
+export interface VideoMetadata {
+ /**
+ * The start offset of the video in
+ * protobuf {@link https://cloud.google.com/ruby/docs/reference/google-cloud-workflows-v1/latest/Google-Protobuf-Duration#json-mapping | Duration} format.
+ */
+ startOffset: string;
+ /**
+ * The end offset of the video in
+ * protobuf {@link https://cloud.google.com/ruby/docs/reference/google-cloud-workflows-v1/latest/Google-Protobuf-Duration#json-mapping | Duration} format.
+ */
+ endOffset: string;
+}
+
+/**
+ * Content part interface if the part represents a {@link FunctionCall}
.
+ * @public
+ */
+export interface FunctionCallPart {
+ text?: never;
+ inlineData?: never;
+ functionCall: FunctionCall;
+ functionResponse?: never;
+}
+
+/**
+ * Content part interface if the part represents {@link FunctionResponse}
.
+ * @public
+ */
+export interface FunctionResponsePart {
+ text?: never;
+ inlineData?: never;
+ functionCall?: never;
+ functionResponse: FunctionResponse;
+}
+
+/**
+ * Content part interface if the part represents {@link FileData}
+ * @public
+ */
+export interface FileDataPart {
+ text?: never;
+ inlineData?: never;
+ functionCall?: never;
+ functionResponse?: never;
+ fileData: FileData;
+}
+
+/**
+ * A predicted {@link FunctionCall}
returned from the model
+ * that contains a string representing the {@link FunctionDeclaration.name}
+ * and a structured JSON object containing the parameters and their values.
+ * @public
+ */
+export interface FunctionCall {
+ name: string;
+ args: object;
+}
+
+/**
+ * The result output from a {@link FunctionCall}
that contains a string
+ * representing the {@link FunctionDeclaration.name}
+ * and a structured JSON object containing any output
+ * from the function is used as context to the model.
+ * This should contain the result of a {@link FunctionCall}
+ * made based on model prediction.
+ * @public
+ */
+export interface FunctionResponse {
+ name: string;
+ response: object;
+}
+
+/**
+ * Interface for sending an image.
+ * @public
+ */
+export interface GenerativeContentBlob {
+ mimeType: string;
+ /**
+ * Image as a base64 string.
+ */
+ data: string;
+}
+
+/**
+ * Data pointing to a file uploaded on Google Cloud Storage.
+ * @public
+ */
+export interface FileData {
+ mimeType: string;
+ fileUri: string;
+}
diff --git a/packages/vertexai/lib/types/enums.ts b/packages/vertexai/lib/types/enums.ts
new file mode 100644
index 0000000000..de2a7109ae
--- /dev/null
+++ b/packages/vertexai/lib/types/enums.ts
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2016-present Invertase Limited & Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this library except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/**
+ * Role is the producer of the content.
+ * @public
+ */
+export type Role = (typeof POSSIBLE_ROLES)[number];
+
+/**
+ * Possible roles.
+ * @public
+ */
+export const POSSIBLE_ROLES = ['user', 'model', 'function', 'system'] as const;
+
+/**
+ * Harm categories that would cause prompts or candidates to be blocked.
+ * @public
+ */
+export enum HarmCategory {
+ HARM_CATEGORY_HATE_SPEECH = 'HARM_CATEGORY_HATE_SPEECH',
+ HARM_CATEGORY_SEXUALLY_EXPLICIT = 'HARM_CATEGORY_SEXUALLY_EXPLICIT',
+ HARM_CATEGORY_HARASSMENT = 'HARM_CATEGORY_HARASSMENT',
+ HARM_CATEGORY_DANGEROUS_CONTENT = 'HARM_CATEGORY_DANGEROUS_CONTENT',
+}
+
+/**
+ * Threshold above which a prompt or candidate will be blocked.
+ * @public
+ */
+export enum HarmBlockThreshold {
+ // Content with NEGLIGIBLE will be allowed.
+ BLOCK_LOW_AND_ABOVE = 'BLOCK_LOW_AND_ABOVE',
+ // Content with NEGLIGIBLE and LOW will be allowed.
+ BLOCK_MEDIUM_AND_ABOVE = 'BLOCK_MEDIUM_AND_ABOVE',
+ // Content with NEGLIGIBLE, LOW, and MEDIUM will be allowed.
+ BLOCK_ONLY_HIGH = 'BLOCK_ONLY_HIGH',
+ // All content will be allowed.
+ BLOCK_NONE = 'BLOCK_NONE',
+}
+
+/**
+ * @public
+ */
+export enum HarmBlockMethod {
+ // The harm block method uses both probability and severity scores.
+ SEVERITY = 'SEVERITY',
+ // The harm block method uses the probability score.
+ PROBABILITY = 'PROBABILITY',
+}
+
+/**
+ * Probability that a prompt or candidate matches a harm category.
+ * @public
+ */
+export enum HarmProbability {
+ // Content has a negligible chance of being unsafe.
+ NEGLIGIBLE = 'NEGLIGIBLE',
+ // Content has a low chance of being unsafe.
+ LOW = 'LOW',
+ // Content has a medium chance of being unsafe.
+ MEDIUM = 'MEDIUM',
+ // Content has a high chance of being unsafe.
+ HIGH = 'HIGH',
+}
+
+/**
+ * Harm severity levels.
+ * @public
+ */
+export enum HarmSeverity {
+ // Negligible level of harm severity.
+ HARM_SEVERITY_NEGLIGIBLE = 'HARM_SEVERITY_NEGLIGIBLE',
+ // Low level of harm severity.
+ HARM_SEVERITY_LOW = 'HARM_SEVERITY_LOW',
+ // Medium level of harm severity.
+ HARM_SEVERITY_MEDIUM = 'HARM_SEVERITY_MEDIUM',
+ // High level of harm severity.
+ HARM_SEVERITY_HIGH = 'HARM_SEVERITY_HIGH',
+}
+
+/**
+ * Reason that a prompt was blocked.
+ * @public
+ */
+export enum BlockReason {
+ // Content was blocked by safety settings.
+ SAFETY = 'SAFETY',
+ // Content was blocked, but the reason is uncategorized.
+ OTHER = 'OTHER',
+}
+
+/**
+ * Reason that a candidate finished.
+ * @public
+ */
+export enum FinishReason {
+ // Natural stop point of the model or provided stop sequence.
+ STOP = 'STOP',
+ // The maximum number of tokens as specified in the request was reached.
+ MAX_TOKENS = 'MAX_TOKENS',
+ // The candidate content was flagged for safety reasons.
+ SAFETY = 'SAFETY',
+ // The candidate content was flagged for recitation reasons.
+ RECITATION = 'RECITATION',
+ // Unknown reason.
+ OTHER = 'OTHER',
+}
+
+/**
+ * @public
+ */
+export enum FunctionCallingMode {
+ // Default model behavior, model decides to predict either a function call
+ // or a natural language response.
+ AUTO = 'AUTO',
+ // Model is constrained to always predicting a function call only.
+ // If "allowed_function_names" is set, the predicted function call will be
+ // limited to any one of "allowed_function_names", else the predicted
+ // function call will be any one of the provided "function_declarations".
+ ANY = 'ANY',
+ // Model will not predict any function call. Model behavior is same as when
+ // not passing any function declarations.
+ NONE = 'NONE',
+}
diff --git a/packages/vertexai/lib/types/error.ts b/packages/vertexai/lib/types/error.ts
new file mode 100644
index 0000000000..33c268204f
--- /dev/null
+++ b/packages/vertexai/lib/types/error.ts
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2016-present Invertase Limited & Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this library except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+import { GenerateContentResponse } from './responses';
+
+/**
+ * Details object that may be included in an error response.
+ *
+ * @public
+ */
+export interface ErrorDetails {
+ '@type'?: string;
+
+ /** The reason for the error. */
+ reason?: string;
+
+ /** The domain where the error occurred. */
+ domain?: string;
+
+ /** Additional metadata about the error. */
+ metadata?: Record;
+
+ /** Any other relevant information about the error. */
+ [key: string]: unknown;
+}
+
+/**
+ * Details object that contains data originating from a bad HTTP response.
+ *
+ * @public
+ */
+export interface CustomErrorData {
+ /** HTTP status code of the error response. */
+ status?: number;
+
+ /** HTTP status text of the error response. */
+ statusText?: string;
+
+ /** Response from a {@link GenerateContentRequest}
*/
+ response?: GenerateContentResponse;
+
+ /** Optional additional details about the error. */
+ errorDetails?: ErrorDetails[];
+}
+
+/**
+ * Standardized error codes that {@link VertexAIError}
can have.
+ *
+ * @public
+ */
+export const enum VertexAIErrorCode {
+ /** A generic error occurred. */
+ ERROR = 'error',
+
+ /** An error occurred in a request. */
+ REQUEST_ERROR = 'request-error',
+
+ /** An error occurred in a response. */
+ RESPONSE_ERROR = 'response-error',
+
+ /** An error occurred while performing a fetch. */
+ FETCH_ERROR = 'fetch-error',
+
+ /** An error associated with a Content object. */
+ INVALID_CONTENT = 'invalid-content',
+
+ /** An error due to the Firebase API not being enabled in the Console. */
+ API_NOT_ENABLED = 'api-not-enabled',
+
+ /** An error due to invalid Schema input. */
+ INVALID_SCHEMA = 'invalid-schema',
+
+ /** An error occurred due to a missing Firebase API key. */
+ NO_API_KEY = 'no-api-key',
+
+ /** An error occurred due to a model name not being specified during initialization. */
+ NO_MODEL = 'no-model',
+
+ /** An error occurred due to a missing project ID. */
+ NO_PROJECT_ID = 'no-project-id',
+
+ /** An error occurred while parsing. */
+ PARSE_FAILED = 'parse-failed',
+}
diff --git a/packages/vertexai/lib/types/index.ts b/packages/vertexai/lib/types/index.ts
new file mode 100644
index 0000000000..5a2b42a426
--- /dev/null
+++ b/packages/vertexai/lib/types/index.ts
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2016-present Invertase Limited & Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this library except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+export * from './content';
+export * from './enums';
+export * from './requests';
+export * from './responses';
+export * from './error';
+export * from './schema';
diff --git a/packages/vertexai/lib/types/internal.ts b/packages/vertexai/lib/types/internal.ts
new file mode 100644
index 0000000000..1aa36f783f
--- /dev/null
+++ b/packages/vertexai/lib/types/internal.ts
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2016-present Invertase Limited & Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this library except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+import { AppCheckTokenResult } from '@firebase/app-check-interop-types';
+import { FirebaseAuthTokenData } from '@firebase/auth-interop-types';
+import { FirebaseApp } from '@firebase/app';
+
+export interface ApiSettings {
+ apiKey: string;
+ project: string;
+ location: string;
+ getAuthToken?: () => Promise;
+ getAppCheckToken?: () => Promise;
+}
+
+/**
+ * @internal
+ */
+// eslint-disable-next-line @typescript-eslint/naming-convention
+export interface _FirebaseService {
+ app: FirebaseApp;
+ /**
+ * Delete the service and free it's resources - called from
+ * {@link @firebase/app#deleteApp | deleteApp()}
+ */
+ _delete(): Promise;
+}
diff --git a/packages/vertexai/lib/types/requests.ts b/packages/vertexai/lib/types/requests.ts
new file mode 100644
index 0000000000..8b36f9c37a
--- /dev/null
+++ b/packages/vertexai/lib/types/requests.ts
@@ -0,0 +1,198 @@
+/*
+ * Copyright (c) 2016-present Invertase Limited & Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this library except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+import { TypedSchema } from '../requests/schema-builder';
+import { Content, Part } from './content';
+import { FunctionCallingMode, HarmBlockMethod, HarmBlockThreshold, HarmCategory } from './enums';
+import { ObjectSchemaInterface, SchemaRequest } from './schema';
+
+/**
+ * Base parameters for a number of methods.
+ * @public
+ */
+export interface BaseParams {
+ safetySettings?: SafetySetting[];
+ generationConfig?: GenerationConfig;
+}
+
+/**
+ * Params passed to {@link getGenerativeModel}
.
+ * @public
+ */
+export interface ModelParams extends BaseParams {
+ model: string;
+ tools?: Tool[];
+ toolConfig?: ToolConfig;
+ systemInstruction?: string | Part | Content;
+}
+
+/**
+ * Request sent through {@link GenerativeModel.generateContent}
+ * @public
+ */
+export interface GenerateContentRequest extends BaseParams {
+ contents: Content[];
+ tools?: Tool[];
+ toolConfig?: ToolConfig;
+ systemInstruction?: string | Part | Content;
+}
+
+/**
+ * Safety setting that can be sent as part of request parameters.
+ * @public
+ */
+export interface SafetySetting {
+ category: HarmCategory;
+ threshold: HarmBlockThreshold;
+ method?: HarmBlockMethod;
+}
+
+/**
+ * Config options for content-related requests
+ * @public
+ */
+export interface GenerationConfig {
+ candidateCount?: number;
+ stopSequences?: string[];
+ maxOutputTokens?: number;
+ temperature?: number;
+ topP?: number;
+ topK?: number;
+ presencePenalty?: number;
+ frequencyPenalty?: number;
+ /**
+ * Output response MIME type of the generated candidate text.
+ * Supported MIME types are `text/plain` (default, text output),
+ * `application/json` (JSON response in the candidates), and
+ * `text/x.enum`.
+ */
+ responseMimeType?: string;
+ /**
+ * Output response schema of the generated candidate text. This
+ * value can be a class generated with a {@link Schema}
static method
+ * like `Schema.string()` or `Schema.object()` or it can be a plain
+ * JS object matching the {@link SchemaRequest}
interface.
+ *
Note: This only applies when the specified `responseMIMEType` supports a schema; currently
+ * this is limited to `application/json` and `text/x.enum`.
+ */
+ responseSchema?: TypedSchema | SchemaRequest;
+}
+
+/**
+ * Params for {@link GenerativeModel.startChat}.
+ * @public
+ */
+export interface StartChatParams extends BaseParams {
+ history?: Content[];
+ tools?: Tool[];
+ toolConfig?: ToolConfig;
+ systemInstruction?: string | Part | Content;
+}
+
+/**
+ * Params for calling {@link GenerativeModel.countTokens}
+ * @public
+ */
+export interface CountTokensRequest {
+ contents: Content[];
+}
+
+/**
+ * Params passed to {@link getGenerativeModel}
.
+ * @public
+ */
+export interface RequestOptions {
+ /**
+ * Request timeout in milliseconds. Defaults to 180 seconds (180000ms).
+ */
+ timeout?: number;
+ /**
+ * Base url for endpoint. Defaults to https://firebasevertexai.googleapis.com
+ */
+ baseUrl?: string;
+}
+
+/**
+ * Defines a tool that model can call to access external knowledge.
+ * @public
+ */
+export declare type Tool = FunctionDeclarationsTool;
+
+/**
+ * Structured representation of a function declaration as defined by the
+ * {@link https://spec.openapis.org/oas/v3.0.3 | OpenAPI 3.0 specification}.
+ * Included
+ * in this declaration are the function name and parameters. This
+ * `FunctionDeclaration` is a representation of a block of code that can be used
+ * as a Tool by the model and executed by the client.
+ * @public
+ */
+export declare interface FunctionDeclaration {
+ /**
+ * The name of the function to call. Must start with a letter or an
+ * underscore. Must be a-z, A-Z, 0-9, or contain underscores and dashes, with
+ * a max length of 64.
+ */
+ name: string;
+ /**
+ * Description and purpose of the function. Model uses it to decide
+ * how and whether to call the function.
+ */
+ description: string;
+ /**
+ * Optional. Describes the parameters to this function in JSON Schema Object
+ * format. Reflects the Open API 3.03 Parameter Object. Parameter names are
+ * case-sensitive. For a function with no parameters, this can be left unset.
+ */
+ parameters?: ObjectSchemaInterface;
+}
+
+/**
+ * A `FunctionDeclarationsTool` is a piece of code that enables the system to
+ * interact with external systems to perform an action, or set of actions,
+ * outside of knowledge and scope of the model.
+ * @public
+ */
+export declare interface FunctionDeclarationsTool {
+ /**
+ * Optional. One or more function declarations
+ * to be passed to the model along with the current user query. Model may
+ * decide to call a subset of these functions by populating
+ * {@link FunctionCall}
in the response. User should
+ * provide a {@link FunctionResponse}
for each
+ * function call in the next turn. Based on the function responses, the model will
+ * generate the final response back to the user. Maximum 64 function
+ * declarations can be provided.
+ */
+ functionDeclarations?: FunctionDeclaration[];
+}
+
+/**
+ * Tool config. This config is shared for all tools provided in the request.
+ * @public
+ */
+export interface ToolConfig {
+ functionCallingConfig?: FunctionCallingConfig;
+}
+
+/**
+ * @public
+ */
+export interface FunctionCallingConfig {
+ mode?: FunctionCallingMode;
+ allowedFunctionNames?: string[];
+}
diff --git a/packages/vertexai/lib/types/responses.ts b/packages/vertexai/lib/types/responses.ts
new file mode 100644
index 0000000000..bcb645677b
--- /dev/null
+++ b/packages/vertexai/lib/types/responses.ts
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 2016-present Invertase Limited & Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this library except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+import { Content, FunctionCall } from './content';
+import { BlockReason, FinishReason, HarmCategory, HarmProbability, HarmSeverity } from './enums';
+
+/**
+ * Result object returned from {@link GenerativeModel.generateContent} call.
+ *
+ * @public
+ */
+export interface GenerateContentResult {
+ response: EnhancedGenerateContentResponse;
+}
+
+/**
+ * Result object returned from {@link GenerativeModel.generateContentStream} call.
+ * Iterate over `stream` to get chunks as they come in and/or
+ * use the `response` promise to get the aggregated response when
+ * the stream is done.
+ *
+ * @public
+ */
+export interface GenerateContentStreamResult {
+ stream: AsyncGenerator;
+ response: Promise;
+}
+
+/**
+ * Response object wrapped with helper methods.
+ *
+ * @public
+ */
+export interface EnhancedGenerateContentResponse extends GenerateContentResponse {
+ /**
+ * Returns the text string from the response, if available.
+ * Throws if the prompt or candidate was blocked.
+ */
+ text: () => string;
+ functionCalls: () => FunctionCall[] | undefined;
+}
+
+/**
+ * Individual response from {@link GenerativeModel.generateContent} and
+ * {@link GenerativeModel.generateContentStream}.
+ * `generateContentStream()` will return one in each chunk until
+ * the stream is done.
+ * @public
+ */
+export interface GenerateContentResponse {
+ candidates?: GenerateContentCandidate[];
+ promptFeedback?: PromptFeedback;
+ usageMetadata?: UsageMetadata;
+}
+
+/**
+ * Usage metadata about a {@link GenerateContentResponse}
.
+ *
+ * @public
+ */
+export interface UsageMetadata {
+ promptTokenCount: number;
+ candidatesTokenCount: number;
+ totalTokenCount: number;
+}
+
+/**
+ * If the prompt was blocked, this will be populated with `blockReason` and
+ * the relevant `safetyRatings`.
+ * @public
+ */
+export interface PromptFeedback {
+ blockReason?: BlockReason;
+ safetyRatings: SafetyRating[];
+ blockReasonMessage?: string;
+}
+
+/**
+ * A candidate returned as part of a {@link GenerateContentResponse}
.
+ * @public
+ */
+export interface GenerateContentCandidate {
+ index: number;
+ content: Content;
+ finishReason?: FinishReason;
+ finishMessage?: string;
+ safetyRatings?: SafetyRating[];
+ citationMetadata?: CitationMetadata;
+ groundingMetadata?: GroundingMetadata;
+}
+
+/**
+ * Citation metadata that may be found on a {@link GenerateContentCandidate}
.
+ * @public
+ */
+export interface CitationMetadata {
+ citations: Citation[];
+}
+
+/**
+ * A single citation.
+ * @public
+ */
+export interface Citation {
+ startIndex?: number;
+ endIndex?: number;
+ uri?: string;
+ license?: string;
+ title?: string;
+ publicationDate?: Date;
+}
+
+/**
+ * Metadata returned to client when grounding is enabled.
+ * @public
+ */
+export interface GroundingMetadata {
+ webSearchQueries?: string[];
+ retrievalQueries?: string[];
+ groundingAttributions: GroundingAttribution[];
+}
+
+/**
+ * @public
+ */
+export interface GroundingAttribution {
+ segment: Segment;
+ confidenceScore?: number;
+ web?: WebAttribution;
+ retrievedContext?: RetrievedContextAttribution;
+}
+
+/**
+ * @public
+ */
+export interface Segment {
+ partIndex: number;
+ startIndex: number;
+ endIndex: number;
+}
+
+/**
+ * @public
+ */
+export interface WebAttribution {
+ uri: string;
+ title: string;
+}
+
+/**
+ * @public
+ */
+export interface RetrievedContextAttribution {
+ uri: string;
+ title: string;
+}
+
+/**
+ * Protobuf google.type.Date
+ * @public
+ */
+export interface Date {
+ year: number;
+ month: number;
+ day: number;
+}
+
+/**
+ * A safety rating associated with a {@link GenerateContentCandidate}
+ * @public
+ */
+export interface SafetyRating {
+ category: HarmCategory;
+ probability: HarmProbability;
+ severity: HarmSeverity;
+ probabilityScore: number;
+ severityScore: number;
+ blocked: boolean;
+}
+
+/**
+ * Response from calling {@link GenerativeModel.countTokens}.
+ * @public
+ */
+export interface CountTokensResponse {
+ /**
+ * The total number of tokens counted across all instances from the request.
+ */
+ totalTokens: number;
+ /**
+ * The total number of billable characters counted across all instances
+ * from the request.
+ */
+ totalBillableCharacters?: number;
+}
diff --git a/packages/vertexai/lib/types/schema.ts b/packages/vertexai/lib/types/schema.ts
new file mode 100644
index 0000000000..f4ca82fdfc
--- /dev/null
+++ b/packages/vertexai/lib/types/schema.ts
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2016-present Invertase Limited & Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this library except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+/**
+ * Contains the list of OpenAPI data types
+ * as defined by the
+ * {@link https://swagger.io/docs/specification/data-models/data-types/ | OpenAPI specification}
+ * @public
+ */
+export enum SchemaType {
+ /** String type. */
+ STRING = 'string',
+ /** Number type. */
+ NUMBER = 'number',
+ /** Integer type. */
+ INTEGER = 'integer',
+ /** Boolean type. */
+ BOOLEAN = 'boolean',
+ /** Array type. */
+ ARRAY = 'array',
+ /** Object type. */
+ OBJECT = 'object',
+}
+
+/**
+ * Basic {@link Schema}
properties shared across several Schema-related
+ * types.
+ * @public
+ */
+export interface SchemaShared {
+ /** Optional. The format of the property. */
+ format?: string;
+ /** Optional. The description of the property. */
+ description?: string;
+ /** Optional. The items of the property. */
+ items?: T;
+ /** Optional. Map of `Schema` objects. */
+ properties?: {
+ [k: string]: T;
+ };
+ /** Optional. The enum of the property. */
+ enum?: string[];
+ /** Optional. The example of the property. */
+ example?: unknown;
+ /** Optional. Whether the property is nullable. */
+ nullable?: boolean;
+ [key: string]: unknown;
+}
+
+/**
+ * Params passed to {@link Schema}
static methods to create specific
+ * {@link Schema}
classes.
+ * @public
+ */
+export interface SchemaParams extends SchemaShared {}
+
+/**
+ * Final format for {@link Schema}
params passed to backend requests.
+ * @public
+ */
+export interface SchemaRequest extends SchemaShared {
+ /**
+ * The type of the property. {@link
+ * SchemaType}.
+ */
+ type: SchemaType;
+ /** Optional. Array of required property. */
+ required?: string[];
+}
+
+/**
+ * Interface for {@link Schema}
class.
+ * @public
+ */
+export interface SchemaInterface extends SchemaShared {
+ /**
+ * The type of the property. {@link
+ * SchemaType}.
+ */
+ type: SchemaType;
+}
+
+/**
+ * Interface for {@link ObjectSchema}
class.
+ * @public
+ */
+export interface ObjectSchemaInterface extends SchemaInterface {
+ type: SchemaType.OBJECT;
+ optionalProperties?: string[];
+}
From 0b2cd5564b42991efe3cd6a3065d03fc1573d288 Mon Sep 17 00:00:00 2001
From: russellwheatley
Date: Wed, 8 Jan 2025 15:26:34 +0000
Subject: [PATCH 006/115] react-native-builder-bob
---
packages/vertexai/package.json | 60 +-
packages/vertexai/tsconfig.json | 27 +
yarn.lock | 1748 ++++++++++++++++++++++++++++++-
3 files changed, 1819 insertions(+), 16 deletions(-)
create mode 100644 packages/vertexai/tsconfig.json
diff --git a/packages/vertexai/package.json b/packages/vertexai/package.json
index 20e216010d..5ef0749728 100644
--- a/packages/vertexai/package.json
+++ b/packages/vertexai/package.json
@@ -3,12 +3,12 @@
"version": "0.0.1",
"author": "Invertase (http://invertase.io)",
"description": "React Native Firebase - Vertex AI is a fully-managed, unified AI development platform for building and using generative AI",
- "main": "lib/index.js",
- "types": "lib/index.d.ts",
+ "main": "./dist/commonjs/index.js",
+ "types": "./dist/typescript/commonjs/lib/index.d.ts",
"scripts": {
"build": "genversion --semi lib/version.js",
"build:clean": "rimraf android/build && rimraf ios/build",
- "prepare": "yarn run build"
+ "prepare": "yarn run build && bob build"
},
"repository": {
"type": "git",
@@ -28,5 +28,57 @@
},
"publishConfig": {
"access": "public"
- }
+ },
+ "devDependencies": {
+ "react-native-builder-bob": "^0.35.2"
+ },
+ "source": "./lib/index.ts",
+ "module": "./dist/module/index.js",
+ "exports": {
+ ".": {
+ "import": {
+ "types": "./dist/typescript/module/lib/index.d.ts",
+ "default": "./dist/module/index.js"
+ },
+ "require": {
+ "types": "./dist/typescript/commonjs/lib/index.d.ts",
+ "default": "./dist/commonjs/index.js"
+ }
+ }
+ },
+ "files": [
+ "lib",
+ "dist",
+ "!**/__tests__",
+ "!**/__fixtures__",
+ "!**/__mocks__"
+ ],
+ "react-native-builder-bob": {
+ "source": "lib",
+ "output": "dist",
+ "targets": [
+ [
+ "commonjs",
+ {
+ "esm": true
+ }
+ ],
+ [
+ "module",
+ {
+ "esm": true
+ }
+ ],
+ [
+ "typescript",
+ {
+ "esm": true
+ }
+ ]
+ ]
+ },
+ "eslintIgnore": [
+ "node_modules/",
+ "dist/"
+ ]
}
diff --git a/packages/vertexai/tsconfig.json b/packages/vertexai/tsconfig.json
new file mode 100644
index 0000000000..356b26154c
--- /dev/null
+++ b/packages/vertexai/tsconfig.json
@@ -0,0 +1,27 @@
+{
+ "compilerOptions": {
+ "rootDir": ".",
+ "allowUnreachableCode": false,
+ "allowUnusedLabels": false,
+ "esModuleInterop": true,
+ "forceConsistentCasingInFileNames": true,
+ "jsx": "react-jsx",
+ "lib": [
+ "ESNext"
+ ],
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "noFallthroughCasesInSwitch": true,
+ "noImplicitReturns": true,
+ "noImplicitUseStrict": false,
+ "noStrictGenericChecks": false,
+ "noUncheckedIndexedAccess": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "resolveJsonModule": true,
+ "skipLibCheck": true,
+ "strict": true,
+ "target": "ESNext",
+ "verbatimModuleSyntax": true
+ }
+}
diff --git a/yarn.lock b/yarn.lock
index 4afe1d5349..675c0562bf 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -75,6 +75,17 @@ __metadata:
languageName: node
linkType: hard
+"@babel/code-frame@npm:^7.25.9, @babel/code-frame@npm:^7.26.2":
+ version: 7.26.2
+ resolution: "@babel/code-frame@npm:7.26.2"
+ dependencies:
+ "@babel/helper-validator-identifier": "npm:^7.25.9"
+ js-tokens: "npm:^4.0.0"
+ picocolors: "npm:^1.0.0"
+ checksum: 10/db2c2122af79d31ca916755331bb4bac96feb2b334cdaca5097a6b467fdd41963b89b14b6836a14f083de7ff887fc78fa1b3c10b14e743d33e12dbfe5ee3d223
+ languageName: node
+ linkType: hard
+
"@babel/compat-data@npm:^7.20.5, @babel/compat-data@npm:^7.22.6, @babel/compat-data@npm:^7.23.3, @babel/compat-data@npm:^7.23.5":
version: 7.23.5
resolution: "@babel/compat-data@npm:7.23.5"
@@ -96,6 +107,13 @@ __metadata:
languageName: node
linkType: hard
+"@babel/compat-data@npm:^7.25.9, @babel/compat-data@npm:^7.26.0":
+ version: 7.26.3
+ resolution: "@babel/compat-data@npm:7.26.3"
+ checksum: 10/0bf4e491680722aa0eac26f770f2fae059f92e2ac083900b241c90a2c10f0fc80e448b1feccc2b332687fab4c3e33e9f83dee9ef56badca1fb9f3f71266d9ebf
+ languageName: node
+ linkType: hard
+
"@babel/core@npm:^7.11.6, @babel/core@npm:^7.12.3, @babel/core@npm:^7.13.16, @babel/core@npm:^7.20.0, @babel/core@npm:^7.23.9":
version: 7.23.9
resolution: "@babel/core@npm:7.23.9"
@@ -213,6 +231,19 @@ __metadata:
languageName: node
linkType: hard
+"@babel/generator@npm:^7.26.3":
+ version: 7.26.3
+ resolution: "@babel/generator@npm:7.26.3"
+ dependencies:
+ "@babel/parser": "npm:^7.26.3"
+ "@babel/types": "npm:^7.26.3"
+ "@jridgewell/gen-mapping": "npm:^0.3.5"
+ "@jridgewell/trace-mapping": "npm:^0.3.25"
+ jsesc: "npm:^3.0.2"
+ checksum: 10/c1d8710cc1c52af9d8d67f7d8ea775578aa500887b327d2a81e27494764a6ef99e438dd7e14cf7cd3153656492ee27a8362980dc438087c0ca39d4e75532c638
+ languageName: node
+ linkType: hard
+
"@babel/helper-annotate-as-pure@npm:^7.18.6, @babel/helper-annotate-as-pure@npm:^7.22.5":
version: 7.22.5
resolution: "@babel/helper-annotate-as-pure@npm:7.22.5"
@@ -231,6 +262,15 @@ __metadata:
languageName: node
linkType: hard
+"@babel/helper-annotate-as-pure@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/helper-annotate-as-pure@npm:7.25.9"
+ dependencies:
+ "@babel/types": "npm:^7.25.9"
+ checksum: 10/41edda10df1ae106a9b4fe617bf7c6df77db992992afd46192534f5cff29f9e49a303231733782dd65c5f9409714a529f215325569f14282046e9d3b7a1ffb6c
+ languageName: node
+ linkType: hard
+
"@babel/helper-builder-binary-assignment-operator-visitor@npm:^7.22.15":
version: 7.22.15
resolution: "@babel/helper-builder-binary-assignment-operator-visitor@npm:7.22.15"
@@ -289,6 +329,19 @@ __metadata:
languageName: node
linkType: hard
+"@babel/helper-compilation-targets@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/helper-compilation-targets@npm:7.25.9"
+ dependencies:
+ "@babel/compat-data": "npm:^7.25.9"
+ "@babel/helper-validator-option": "npm:^7.25.9"
+ browserslist: "npm:^4.24.0"
+ lru-cache: "npm:^5.1.1"
+ semver: "npm:^6.3.1"
+ checksum: 10/8053fbfc21e8297ab55c8e7f9f119e4809fa7e505268691e1bedc2cf5e7a5a7de8c60ad13da2515378621b7601c42e101d2d679904da395fa3806a1edef6b92e
+ languageName: node
+ linkType: hard
+
"@babel/helper-create-class-features-plugin@npm:^7.18.6, @babel/helper-create-class-features-plugin@npm:^7.21.0, @babel/helper-create-class-features-plugin@npm:^7.22.15, @babel/helper-create-class-features-plugin@npm:^7.23.6, @babel/helper-create-class-features-plugin@npm:^7.23.9":
version: 7.23.10
resolution: "@babel/helper-create-class-features-plugin@npm:7.23.10"
@@ -344,6 +397,23 @@ __metadata:
languageName: node
linkType: hard
+"@babel/helper-create-class-features-plugin@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/helper-create-class-features-plugin@npm:7.25.9"
+ dependencies:
+ "@babel/helper-annotate-as-pure": "npm:^7.25.9"
+ "@babel/helper-member-expression-to-functions": "npm:^7.25.9"
+ "@babel/helper-optimise-call-expression": "npm:^7.25.9"
+ "@babel/helper-replace-supers": "npm:^7.25.9"
+ "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.25.9"
+ "@babel/traverse": "npm:^7.25.9"
+ semver: "npm:^6.3.1"
+ peerDependencies:
+ "@babel/core": ^7.0.0
+ checksum: 10/d1d47a7b5fd317c6cb1446b0e4f4892c19ddaa69ea0229f04ba8bea5f273fc8168441e7114ad36ff919f2d310f97310cec51adc79002e22039a7e1640ccaf248
+ languageName: node
+ linkType: hard
+
"@babel/helper-create-regexp-features-plugin@npm:^7.18.6, @babel/helper-create-regexp-features-plugin@npm:^7.22.15, @babel/helper-create-regexp-features-plugin@npm:^7.22.5":
version: 7.22.15
resolution: "@babel/helper-create-regexp-features-plugin@npm:7.22.15"
@@ -383,6 +453,19 @@ __metadata:
languageName: node
linkType: hard
+"@babel/helper-create-regexp-features-plugin@npm:^7.25.9":
+ version: 7.26.3
+ resolution: "@babel/helper-create-regexp-features-plugin@npm:7.26.3"
+ dependencies:
+ "@babel/helper-annotate-as-pure": "npm:^7.25.9"
+ regexpu-core: "npm:^6.2.0"
+ semver: "npm:^6.3.1"
+ peerDependencies:
+ "@babel/core": ^7.0.0
+ checksum: 10/4c44122ea11c4253ee78a9c083b7fbce96c725e2cb43cc864f0e8ea2749f7b6658617239c6278df9f132d09a7545c8fe0336ed2895ad7c80c71507828a7bc8ba
+ languageName: node
+ linkType: hard
+
"@babel/helper-define-polyfill-provider@npm:^0.5.0":
version: 0.5.0
resolution: "@babel/helper-define-polyfill-provider@npm:0.5.0"
@@ -511,6 +594,16 @@ __metadata:
languageName: node
linkType: hard
+"@babel/helper-member-expression-to-functions@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/helper-member-expression-to-functions@npm:7.25.9"
+ dependencies:
+ "@babel/traverse": "npm:^7.25.9"
+ "@babel/types": "npm:^7.25.9"
+ checksum: 10/ef8cc1c1e600b012b312315f843226545a1a89f25d2f474ce2503fd939ca3f8585180f291a3a13efc56cf13eddc1d41a3a040eae9a521838fd59a6d04cc82490
+ languageName: node
+ linkType: hard
+
"@babel/helper-module-imports@npm:^7.22.15":
version: 7.22.15
resolution: "@babel/helper-module-imports@npm:7.22.15"
@@ -530,6 +623,16 @@ __metadata:
languageName: node
linkType: hard
+"@babel/helper-module-imports@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/helper-module-imports@npm:7.25.9"
+ dependencies:
+ "@babel/traverse": "npm:^7.25.9"
+ "@babel/types": "npm:^7.25.9"
+ checksum: 10/e090be5dee94dda6cd769972231b21ddfae988acd76b703a480ac0c96f3334557d70a965bf41245d6ee43891e7571a8b400ccf2b2be5803351375d0f4e5bcf08
+ languageName: node
+ linkType: hard
+
"@babel/helper-module-transforms@npm:^7.23.3":
version: 7.23.3
resolution: "@babel/helper-module-transforms@npm:7.23.3"
@@ -574,6 +677,19 @@ __metadata:
languageName: node
linkType: hard
+"@babel/helper-module-transforms@npm:^7.25.9, @babel/helper-module-transforms@npm:^7.26.0":
+ version: 7.26.0
+ resolution: "@babel/helper-module-transforms@npm:7.26.0"
+ dependencies:
+ "@babel/helper-module-imports": "npm:^7.25.9"
+ "@babel/helper-validator-identifier": "npm:^7.25.9"
+ "@babel/traverse": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0
+ checksum: 10/9841d2a62f61ad52b66a72d08264f23052d533afc4ce07aec2a6202adac0bfe43014c312f94feacb3291f4c5aafe681955610041ece2c276271adce3f570f2f5
+ languageName: node
+ linkType: hard
+
"@babel/helper-optimise-call-expression@npm:^7.22.5":
version: 7.22.5
resolution: "@babel/helper-optimise-call-expression@npm:7.22.5"
@@ -592,6 +708,15 @@ __metadata:
languageName: node
linkType: hard
+"@babel/helper-optimise-call-expression@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/helper-optimise-call-expression@npm:7.25.9"
+ dependencies:
+ "@babel/types": "npm:^7.25.9"
+ checksum: 10/f09d0ad60c0715b9a60c31841b3246b47d67650c512ce85bbe24a3124f1a4d66377df793af393273bc6e1015b0a9c799626c48e53747581c1582b99167cc65dc
+ languageName: node
+ linkType: hard
+
"@babel/helper-plugin-utils@npm:^7.0.0, @babel/helper-plugin-utils@npm:^7.10.4, @babel/helper-plugin-utils@npm:^7.12.13, @babel/helper-plugin-utils@npm:^7.14.5, @babel/helper-plugin-utils@npm:^7.18.6, @babel/helper-plugin-utils@npm:^7.20.2, @babel/helper-plugin-utils@npm:^7.22.5, @babel/helper-plugin-utils@npm:^7.8.0, @babel/helper-plugin-utils@npm:^7.8.3":
version: 7.22.5
resolution: "@babel/helper-plugin-utils@npm:7.22.5"
@@ -620,6 +745,13 @@ __metadata:
languageName: node
linkType: hard
+"@babel/helper-plugin-utils@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/helper-plugin-utils@npm:7.25.9"
+ checksum: 10/e347d87728b1ab10b6976d46403941c8f9008c045ea6d99997a7ffca7b852dc34b6171380f7b17edf94410e0857ff26f3a53d8618f11d73744db86e8ca9b8c64
+ languageName: node
+ linkType: hard
+
"@babel/helper-remap-async-to-generator@npm:^7.18.9, @babel/helper-remap-async-to-generator@npm:^7.22.20":
version: 7.22.20
resolution: "@babel/helper-remap-async-to-generator@npm:7.22.20"
@@ -659,6 +791,19 @@ __metadata:
languageName: node
linkType: hard
+"@babel/helper-remap-async-to-generator@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/helper-remap-async-to-generator@npm:7.25.9"
+ dependencies:
+ "@babel/helper-annotate-as-pure": "npm:^7.25.9"
+ "@babel/helper-wrap-function": "npm:^7.25.9"
+ "@babel/traverse": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0
+ checksum: 10/ea37ad9f8f7bcc27c109963b8ebb9d22bac7a5db2a51de199cb560e251d5593fe721e46aab2ca7d3e7a24b0aa4aff0eaf9c7307af9c2fd3a1d84268579073052
+ languageName: node
+ linkType: hard
+
"@babel/helper-replace-supers@npm:^7.22.20":
version: 7.22.20
resolution: "@babel/helper-replace-supers@npm:7.22.20"
@@ -711,6 +856,19 @@ __metadata:
languageName: node
linkType: hard
+"@babel/helper-replace-supers@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/helper-replace-supers@npm:7.25.9"
+ dependencies:
+ "@babel/helper-member-expression-to-functions": "npm:^7.25.9"
+ "@babel/helper-optimise-call-expression": "npm:^7.25.9"
+ "@babel/traverse": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0
+ checksum: 10/8ebf787016953e4479b99007bac735c9c860822fafc51bc3db67bc53814539888797238c81fa8b948b6da897eb7b1c1d4f04df11e501a7f0596b356be02de2ab
+ languageName: node
+ linkType: hard
+
"@babel/helper-simple-access@npm:^7.22.5":
version: 7.22.5
resolution: "@babel/helper-simple-access@npm:7.22.5"
@@ -749,6 +907,16 @@ __metadata:
languageName: node
linkType: hard
+"@babel/helper-skip-transparent-expression-wrappers@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/helper-skip-transparent-expression-wrappers@npm:7.25.9"
+ dependencies:
+ "@babel/traverse": "npm:^7.25.9"
+ "@babel/types": "npm:^7.25.9"
+ checksum: 10/fdbb5248932198bc26daa6abf0d2ac42cab9c2dbb75b7e9f40d425c8f28f09620b886d40e7f9e4e08ffc7aaa2cefe6fc2c44be7c20e81f7526634702fb615bdc
+ languageName: node
+ linkType: hard
+
"@babel/helper-split-export-declaration@npm:^7.22.6":
version: 7.22.6
resolution: "@babel/helper-split-export-declaration@npm:7.22.6"
@@ -788,6 +956,13 @@ __metadata:
languageName: node
linkType: hard
+"@babel/helper-string-parser@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/helper-string-parser@npm:7.25.9"
+ checksum: 10/c28656c52bd48e8c1d9f3e8e68ecafd09d949c57755b0d353739eb4eae7ba4f7e67e92e4036f1cd43378cc1397a2c943ed7bcaf5949b04ab48607def0258b775
+ languageName: node
+ linkType: hard
+
"@babel/helper-validator-identifier@npm:^7.22.20":
version: 7.22.20
resolution: "@babel/helper-validator-identifier@npm:7.22.20"
@@ -802,6 +977,13 @@ __metadata:
languageName: node
linkType: hard
+"@babel/helper-validator-identifier@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/helper-validator-identifier@npm:7.25.9"
+ checksum: 10/3f9b649be0c2fd457fa1957b694b4e69532a668866b8a0d81eabfa34ba16dbf3107b39e0e7144c55c3c652bf773ec816af8df4a61273a2bb4eb3145ca9cf478e
+ languageName: node
+ linkType: hard
+
"@babel/helper-validator-option@npm:^7.22.15, @babel/helper-validator-option@npm:^7.23.5":
version: 7.23.5
resolution: "@babel/helper-validator-option@npm:7.23.5"
@@ -823,6 +1005,13 @@ __metadata:
languageName: node
linkType: hard
+"@babel/helper-validator-option@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/helper-validator-option@npm:7.25.9"
+ checksum: 10/9491b2755948ebbdd68f87da907283698e663b5af2d2b1b02a2765761974b1120d5d8d49e9175b167f16f72748ffceec8c9cf62acfbee73f4904507b246e2b3d
+ languageName: node
+ linkType: hard
+
"@babel/helper-wrap-function@npm:^7.22.20":
version: 7.22.20
resolution: "@babel/helper-wrap-function@npm:7.22.20"
@@ -857,6 +1046,17 @@ __metadata:
languageName: node
linkType: hard
+"@babel/helper-wrap-function@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/helper-wrap-function@npm:7.25.9"
+ dependencies:
+ "@babel/template": "npm:^7.25.9"
+ "@babel/traverse": "npm:^7.25.9"
+ "@babel/types": "npm:^7.25.9"
+ checksum: 10/988dcf49159f1c920d6b9486762a93767a6e84b5e593a6342bc235f3e47cc1cb0c048d8fca531a48143e6b7fce1ff12ddbf735cf5f62cb2f07192cf7c27b89cf
+ languageName: node
+ linkType: hard
+
"@babel/helpers@npm:^7.23.9":
version: 7.23.9
resolution: "@babel/helpers@npm:7.23.9"
@@ -940,6 +1140,17 @@ __metadata:
languageName: node
linkType: hard
+"@babel/parser@npm:^7.25.9, @babel/parser@npm:^7.26.3":
+ version: 7.26.3
+ resolution: "@babel/parser@npm:7.26.3"
+ dependencies:
+ "@babel/types": "npm:^7.26.3"
+ bin:
+ parser: ./bin/babel-parser.js
+ checksum: 10/e7e3814b2dc9ee3ed605d38223471fa7d3a84cbe9474d2b5fa7ac57dc1ddf75577b1fd3a93bf7db8f41f28869bda795cddd80223f980be23623b6434bf4c88a8
+ languageName: node
+ linkType: hard
+
"@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:^7.25.3":
version: 7.25.3
resolution: "@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:7.25.3"
@@ -952,6 +1163,18 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:7.25.9"
+ dependencies:
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ "@babel/traverse": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0
+ checksum: 10/3c23ef34e3fd7da3578428cb488180ab6b7b96c9c141438374b6d87fa814d87de099f28098e5fc64726c19193a1da397e4d2351d40b459bcd2489993557e2c74
+ languageName: node
+ linkType: hard
+
"@babel/plugin-bugfix-safari-class-field-initializer-scope@npm:^7.25.0":
version: 7.25.0
resolution: "@babel/plugin-bugfix-safari-class-field-initializer-scope@npm:7.25.0"
@@ -963,6 +1186,17 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-bugfix-safari-class-field-initializer-scope@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-bugfix-safari-class-field-initializer-scope@npm:7.25.9"
+ dependencies:
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0
+ checksum: 10/d3e14ab1cb9cb50246d20cab9539f2fbd1e7ef1ded73980c8ad7c0561b4d5e0b144d362225f0976d47898e04cbd40f2000e208b0913bd788346cf7791b96af91
+ languageName: node
+ linkType: hard
+
"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:^7.23.3":
version: 7.23.3
resolution: "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:7.23.3"
@@ -985,6 +1219,17 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:7.25.9"
+ dependencies:
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0
+ checksum: 10/a9d1ee3fd100d3eb6799a2f2bbd785296f356c531d75c9369f71541811fa324270258a374db103ce159156d006da2f33370330558d0133e6f7584152c34997ca
+ languageName: node
+ linkType: hard
+
"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:^7.23.3":
version: 7.23.3
resolution: "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:7.23.3"
@@ -1011,6 +1256,19 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:7.25.9"
+ dependencies:
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.25.9"
+ "@babel/plugin-transform-optional-chaining": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.13.0
+ checksum: 10/5b298b28e156f64de51cdb03a2c5b80c7f978815ef1026f3ae8b9fc48d28bf0a83817d8fbecb61ef8fb94a7201f62cca5103cc6e7b9e8f28e38f766d7905b378
+ languageName: node
+ linkType: hard
+
"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:^7.23.7":
version: 7.23.7
resolution: "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:7.23.7"
@@ -1035,6 +1293,18 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:7.25.9"
+ dependencies:
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ "@babel/traverse": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0
+ checksum: 10/cb893e5deb9312a0120a399835b6614a016c036714de7123c8edabccc56a09c4455016e083c5c4dd485248546d4e5e55fc0e9132b3c3a9bd16abf534138fe3f2
+ languageName: node
+ linkType: hard
+
"@babel/plugin-proposal-async-generator-functions@npm:^7.0.0":
version: 7.20.7
resolution: "@babel/plugin-proposal-async-generator-functions@npm:7.20.7"
@@ -1307,6 +1577,17 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-syntax-flow@npm:^7.25.9":
+ version: 7.26.0
+ resolution: "@babel/plugin-syntax-flow@npm:7.26.0"
+ dependencies:
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10/fdc0d0a7b512e00d933e12cf93c785ea4645a193f4b539230b7601cfaa8c704410199318ce9ea14e5fca7d13e9027822f7d81a7871d3e854df26b6af04cc3c6c
+ languageName: node
+ linkType: hard
+
"@babel/plugin-syntax-import-assertions@npm:^7.23.3":
version: 7.23.3
resolution: "@babel/plugin-syntax-import-assertions@npm:7.23.3"
@@ -1329,6 +1610,17 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-syntax-import-assertions@npm:^7.26.0":
+ version: 7.26.0
+ resolution: "@babel/plugin-syntax-import-assertions@npm:7.26.0"
+ dependencies:
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10/b58f2306df4a690ca90b763d832ec05202c50af787158ff8b50cdf3354359710bce2e1eb2b5135fcabf284756ac8eadf09ca74764aa7e76d12a5cac5f6b21e67
+ languageName: node
+ linkType: hard
+
"@babel/plugin-syntax-import-attributes@npm:^7.23.3":
version: 7.23.3
resolution: "@babel/plugin-syntax-import-attributes@npm:7.23.3"
@@ -1351,6 +1643,17 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-syntax-import-attributes@npm:^7.26.0":
+ version: 7.26.0
+ resolution: "@babel/plugin-syntax-import-attributes@npm:7.26.0"
+ dependencies:
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10/c122aa577166c80ee67f75aebebeef4150a132c4d3109d25d7fc058bf802946f883e330f20b78c1d3e3a5ada631c8780c263d2d01b5dbaecc69efefeedd42916
+ languageName: node
+ linkType: hard
+
"@babel/plugin-syntax-import-meta@npm:^7.10.4, @babel/plugin-syntax-import-meta@npm:^7.8.3":
version: 7.10.4
resolution: "@babel/plugin-syntax-import-meta@npm:7.10.4"
@@ -1395,6 +1698,17 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-syntax-jsx@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-syntax-jsx@npm:7.25.9"
+ dependencies:
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10/bb609d1ffb50b58f0c1bac8810d0e46a4f6c922aa171c458f3a19d66ee545d36e782d3bffbbc1fed0dc65a558bdce1caf5279316583c0fff5a2c1658982a8563
+ languageName: node
+ linkType: hard
+
"@babel/plugin-syntax-logical-assignment-operators@npm:^7.10.4, @babel/plugin-syntax-logical-assignment-operators@npm:^7.8.3":
version: 7.10.4
resolution: "@babel/plugin-syntax-logical-assignment-operators@npm:7.10.4"
@@ -1494,6 +1808,17 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-syntax-typescript@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-syntax-typescript@npm:7.25.9"
+ dependencies:
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10/0e9821e8ba7d660c36c919654e4144a70546942ae184e85b8102f2322451eae102cbfadbcadd52ce077a2b44b400ee52394c616feab7b5b9f791b910e933fd33
+ languageName: node
+ linkType: hard
+
"@babel/plugin-syntax-unicode-sets-regex@npm:^7.18.6":
version: 7.18.6
resolution: "@babel/plugin-syntax-unicode-sets-regex@npm:7.18.6"
@@ -1528,6 +1853,17 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-transform-arrow-functions@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-arrow-functions@npm:7.25.9"
+ dependencies:
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10/c29f081224859483accf55fb4d091db2aac0dcd0d7954bac5ca889030cc498d3f771aa20eb2e9cd8310084ec394d85fa084b97faf09298b6bc9541182b3eb5bb
+ languageName: node
+ linkType: hard
+
"@babel/plugin-transform-async-generator-functions@npm:^7.23.9":
version: 7.23.9
resolution: "@babel/plugin-transform-async-generator-functions@npm:7.23.9"
@@ -1556,6 +1892,19 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-transform-async-generator-functions@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-async-generator-functions@npm:7.25.9"
+ dependencies:
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ "@babel/helper-remap-async-to-generator": "npm:^7.25.9"
+ "@babel/traverse": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10/99306c44a4a791abd51a56d89fa61c4cfe805a58e070c7fb1cbf950886778a6c8c4f25a92d231f91da1746d14a338436073fd83038e607f03a2a98ac5340406b
+ languageName: node
+ linkType: hard
+
"@babel/plugin-transform-async-to-generator@npm:^7.20.0, @babel/plugin-transform-async-to-generator@npm:^7.23.3":
version: 7.23.3
resolution: "@babel/plugin-transform-async-to-generator@npm:7.23.3"
@@ -1582,6 +1931,19 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-transform-async-to-generator@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-async-to-generator@npm:7.25.9"
+ dependencies:
+ "@babel/helper-module-imports": "npm:^7.25.9"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ "@babel/helper-remap-async-to-generator": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10/b3ad50fb93c171644d501864620ed23952a46648c4df10dc9c62cc9ad08031b66bd272cfdd708faeee07c23b6251b16f29ce0350473e4c79f0c32178d38ce3a6
+ languageName: node
+ linkType: hard
+
"@babel/plugin-transform-block-scoped-functions@npm:^7.0.0":
version: 7.24.1
resolution: "@babel/plugin-transform-block-scoped-functions@npm:7.24.1"
@@ -1615,6 +1977,17 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-transform-block-scoped-functions@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-block-scoped-functions@npm:7.25.9"
+ dependencies:
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10/bf31896556b33a80f017af3d445ceb532ec0f5ca9d69bc211a963ac92514d172d5c24c5ac319f384d9dfa7f1a4d8dc23032c2fe3e74f98a59467ecd86f7033ae
+ languageName: node
+ linkType: hard
+
"@babel/plugin-transform-block-scoping@npm:^7.0.0, @babel/plugin-transform-block-scoping@npm:^7.23.4":
version: 7.23.4
resolution: "@babel/plugin-transform-block-scoping@npm:7.23.4"
@@ -1637,6 +2010,17 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-transform-block-scoping@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-block-scoping@npm:7.25.9"
+ dependencies:
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10/89dcdd7edb1e0c2f44e3c568a8ad8202e2574a8a8308248550a9391540bc3f5c9fbd8352c60ae90769d46f58d3ab36f2c3a0fbc1c3620813d92ff6fccdfa79c8
+ languageName: node
+ linkType: hard
+
"@babel/plugin-transform-class-properties@npm:^7.23.3":
version: 7.23.3
resolution: "@babel/plugin-transform-class-properties@npm:7.23.3"
@@ -1661,6 +2045,18 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-transform-class-properties@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-class-properties@npm:7.25.9"
+ dependencies:
+ "@babel/helper-create-class-features-plugin": "npm:^7.25.9"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10/a8d69e2c285486b63f49193cbcf7a15e1d3a5f632c1c07d7a97f65306df7f554b30270b7378dde143f8b557d1f8f6336c643377943dec8ec405e4cd11e90b9ea
+ languageName: node
+ linkType: hard
+
"@babel/plugin-transform-class-static-block@npm:^7.23.4":
version: 7.23.4
resolution: "@babel/plugin-transform-class-static-block@npm:7.23.4"
@@ -1687,6 +2083,18 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-transform-class-static-block@npm:^7.26.0":
+ version: 7.26.0
+ resolution: "@babel/plugin-transform-class-static-block@npm:7.26.0"
+ dependencies:
+ "@babel/helper-create-class-features-plugin": "npm:^7.25.9"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.12.0
+ checksum: 10/60cba3f125a7bc4f90706af0a011697c7ffd2eddfba336ed6f84c5f358c44c3161af18b0202475241a96dee7964d96dd3a342f46dbf85b75b38bb789326e1766
+ languageName: node
+ linkType: hard
+
"@babel/plugin-transform-classes@npm:^7.0.0, @babel/plugin-transform-classes@npm:^7.23.8":
version: 7.23.8
resolution: "@babel/plugin-transform-classes@npm:7.23.8"
@@ -1721,6 +2129,22 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-transform-classes@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-classes@npm:7.25.9"
+ dependencies:
+ "@babel/helper-annotate-as-pure": "npm:^7.25.9"
+ "@babel/helper-compilation-targets": "npm:^7.25.9"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ "@babel/helper-replace-supers": "npm:^7.25.9"
+ "@babel/traverse": "npm:^7.25.9"
+ globals: "npm:^11.1.0"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10/1914ebe152f35c667fba7bf17ce0d9d0f33df2fb4491990ce9bb1f9ec5ae8cbd11d95b0dc371f7a4cc5e7ce4cf89467c3e34857302911fc6bfb6494a77f7b37e
+ languageName: node
+ linkType: hard
+
"@babel/plugin-transform-computed-properties@npm:^7.0.0, @babel/plugin-transform-computed-properties@npm:^7.23.3":
version: 7.23.3
resolution: "@babel/plugin-transform-computed-properties@npm:7.23.3"
@@ -1745,6 +2169,18 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-transform-computed-properties@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-computed-properties@npm:7.25.9"
+ dependencies:
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ "@babel/template": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10/aa1a9064d6a9d3b569b8cae6972437315a38a8f6553ee618406da5122500a06c2f20b9fa93aeed04dd895923bf6f529c09fc79d4be987ec41785ceb7d2203122
+ languageName: node
+ linkType: hard
+
"@babel/plugin-transform-destructuring@npm:^7.0.0":
version: 7.24.1
resolution: "@babel/plugin-transform-destructuring@npm:7.24.1"
@@ -1778,6 +2214,17 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-transform-destructuring@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-destructuring@npm:7.25.9"
+ dependencies:
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10/51b24fbead910ad0547463b2d214dd08076b22a66234b9f878b8bac117603dd23e05090ff86e9ffc373214de23d3e5bf1b095fe54cce2ca16b010264d90cf4f5
+ languageName: node
+ linkType: hard
+
"@babel/plugin-transform-dotall-regex@npm:^7.23.3":
version: 7.23.3
resolution: "@babel/plugin-transform-dotall-regex@npm:7.23.3"
@@ -1802,6 +2249,18 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-transform-dotall-regex@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-dotall-regex@npm:7.25.9"
+ dependencies:
+ "@babel/helper-create-regexp-features-plugin": "npm:^7.25.9"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10/8bdf1bb9e6e3a2cc8154ae88a3872faa6dc346d6901994505fb43ac85f858728781f1219f40b67f7bb0687c507450236cb7838ac68d457e65637f98500aa161b
+ languageName: node
+ linkType: hard
+
"@babel/plugin-transform-duplicate-keys@npm:^7.23.3":
version: 7.23.3
resolution: "@babel/plugin-transform-duplicate-keys@npm:7.23.3"
@@ -1824,6 +2283,17 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-transform-duplicate-keys@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-duplicate-keys@npm:7.25.9"
+ dependencies:
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10/10dbb87bc09582416f9f97ca6c40563655abf33e3fd0fee25eeaeff28e946a06651192112a2bc2b18c314a638fa15c55b8365a677ef67aa490848cefdc57e1d8
+ languageName: node
+ linkType: hard
+
"@babel/plugin-transform-duplicate-named-capturing-groups-regex@npm:^7.25.0":
version: 7.25.0
resolution: "@babel/plugin-transform-duplicate-named-capturing-groups-regex@npm:7.25.0"
@@ -1836,6 +2306,18 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-transform-duplicate-named-capturing-groups-regex@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-duplicate-named-capturing-groups-regex@npm:7.25.9"
+ dependencies:
+ "@babel/helper-create-regexp-features-plugin": "npm:^7.25.9"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0
+ checksum: 10/f7233cf596be8c6843d31951afaf2464a62a610cb89c72c818c044765827fab78403ab8a7d3a6386f838c8df574668e2a48f6c206b1d7da965aff9c6886cb8e6
+ languageName: node
+ linkType: hard
+
"@babel/plugin-transform-dynamic-import@npm:^7.23.4":
version: 7.23.4
resolution: "@babel/plugin-transform-dynamic-import@npm:7.23.4"
@@ -1860,6 +2342,17 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-transform-dynamic-import@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-dynamic-import@npm:7.25.9"
+ dependencies:
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10/aaca1ccda819be9b2b85af47ba08ddd2210ff2dbea222f26e4cd33f97ab020884bf81a66197e50872721e9daf36ceb5659502c82199884ea74d5d75ecda5c58b
+ languageName: node
+ linkType: hard
+
"@babel/plugin-transform-exponentiation-operator@npm:^7.23.3":
version: 7.23.3
resolution: "@babel/plugin-transform-exponentiation-operator@npm:7.23.3"
@@ -1884,6 +2377,17 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-transform-exponentiation-operator@npm:^7.25.9":
+ version: 7.26.3
+ resolution: "@babel/plugin-transform-exponentiation-operator@npm:7.26.3"
+ dependencies:
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10/0d8da2e552a50a775fe8e6e3c32621d20d3c5d1af7ab40ca2f5c7603de057b57b1b5850f74040e4ecbe36c09ac86d92173ad1e223a2a3b3df3cc359ca4349738
+ languageName: node
+ linkType: hard
+
"@babel/plugin-transform-export-namespace-from@npm:^7.22.11":
version: 7.24.1
resolution: "@babel/plugin-transform-export-namespace-from@npm:7.24.1"
@@ -1920,6 +2424,17 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-transform-export-namespace-from@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-export-namespace-from@npm:7.25.9"
+ dependencies:
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10/4dfe8df86c5b1d085d591290874bb2d78a9063090d71567ed657a418010ad333c3f48af2c974b865f53bbb718987a065f89828d43279a7751db1a56c9229078d
+ languageName: node
+ linkType: hard
+
"@babel/plugin-transform-flow-strip-types@npm:^7.0.0":
version: 7.24.1
resolution: "@babel/plugin-transform-flow-strip-types@npm:7.24.1"
@@ -1944,6 +2459,18 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-transform-flow-strip-types@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-flow-strip-types@npm:7.25.9"
+ dependencies:
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ "@babel/plugin-syntax-flow": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10/a3ffc76bbc922720debe973bccb501ccbda0d6d32d80c9efd599ab1b683fd72cae3198975d8609b37070fc32f921a9eb7d2db17b7b719395468773be41011822
+ languageName: node
+ linkType: hard
+
"@babel/plugin-transform-for-of@npm:^7.0.0":
version: 7.24.1
resolution: "@babel/plugin-transform-for-of@npm:7.24.1"
@@ -1980,6 +2507,18 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-transform-for-of@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-for-of@npm:7.25.9"
+ dependencies:
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10/63a2db7fe06c2e3f5fc1926f478dac66a5f7b3eaeb4a0ffae577e6f3cb3d822cb1ed2ed3798f70f5cb1aa06bc2ad8bcd1f557342f5c425fd83c37a8fc1cfd2ba
+ languageName: node
+ linkType: hard
+
"@babel/plugin-transform-function-name@npm:^7.0.0, @babel/plugin-transform-function-name@npm:^7.23.3":
version: 7.23.3
resolution: "@babel/plugin-transform-function-name@npm:7.23.3"
@@ -2006,6 +2545,19 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-transform-function-name@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-function-name@npm:7.25.9"
+ dependencies:
+ "@babel/helper-compilation-targets": "npm:^7.25.9"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ "@babel/traverse": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10/a8d7c8d019a6eb57eab5ca1be3e3236f175557d55b1f3b11f8ad7999e3fbb1cf37905fd8cb3a349bffb4163a558e9f33b63f631597fdc97c858757deac1b2fd7
+ languageName: node
+ linkType: hard
+
"@babel/plugin-transform-json-strings@npm:^7.23.4":
version: 7.23.4
resolution: "@babel/plugin-transform-json-strings@npm:7.23.4"
@@ -2030,6 +2582,17 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-transform-json-strings@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-json-strings@npm:7.25.9"
+ dependencies:
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10/e2498d84761cfd05aaea53799933d55af309c9d6204e66b38778792d171e4d1311ad34f334259a3aa3407dd0446f6bd3e390a1fcb8ce2e42fe5aabed0e41bee1
+ languageName: node
+ linkType: hard
+
"@babel/plugin-transform-literals@npm:^7.0.0, @babel/plugin-transform-literals@npm:^7.23.3":
version: 7.23.3
resolution: "@babel/plugin-transform-literals@npm:7.23.3"
@@ -2052,6 +2615,17 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-transform-literals@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-literals@npm:7.25.9"
+ dependencies:
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10/3cca75823a38aab599bc151b0fa4d816b5e1b62d6e49c156aa90436deb6e13649f5505973151a10418b64f3f9d1c3da53e38a186402e0ed7ad98e482e70c0c14
+ languageName: node
+ linkType: hard
+
"@babel/plugin-transform-logical-assignment-operators@npm:^7.23.4":
version: 7.23.4
resolution: "@babel/plugin-transform-logical-assignment-operators@npm:7.23.4"
@@ -2076,6 +2650,17 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-transform-logical-assignment-operators@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-logical-assignment-operators@npm:7.25.9"
+ dependencies:
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10/8c6febb4ac53852314d28b5e2c23d5dbbff7bf1e57d61f9672e0d97531ef7778b3f0ad698dcf1179f5486e626c77127508916a65eb846a89e98a92f70ed3537b
+ languageName: node
+ linkType: hard
+
"@babel/plugin-transform-member-expression-literals@npm:^7.0.0":
version: 7.24.1
resolution: "@babel/plugin-transform-member-expression-literals@npm:7.24.1"
@@ -2109,6 +2694,17 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-transform-member-expression-literals@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-member-expression-literals@npm:7.25.9"
+ dependencies:
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10/db92041ae87b8f59f98b50359e0bb172480f6ba22e5e76b13bdfe07122cbf0daa9cd8ad2e78dcb47939938fed88ad57ab5989346f64b3a16953fc73dea3a9b1f
+ languageName: node
+ linkType: hard
+
"@babel/plugin-transform-modules-amd@npm:^7.23.3":
version: 7.23.3
resolution: "@babel/plugin-transform-modules-amd@npm:7.23.3"
@@ -2133,6 +2729,18 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-transform-modules-amd@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-modules-amd@npm:7.25.9"
+ dependencies:
+ "@babel/helper-module-transforms": "npm:^7.25.9"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10/75d34c6e709a23bcfa0e06f722c9a72b1d9ac3e7d72a07ef54a943d32f65f97cbbf0e387d874eb9d9b4c8d33045edfa8e8441d0f8794f3c2b9f1d71b928acf2c
+ languageName: node
+ linkType: hard
+
"@babel/plugin-transform-modules-commonjs@npm:^7.0.0, @babel/plugin-transform-modules-commonjs@npm:^7.13.8, @babel/plugin-transform-modules-commonjs@npm:^7.23.3":
version: 7.23.3
resolution: "@babel/plugin-transform-modules-commonjs@npm:7.23.3"
@@ -2159,6 +2767,18 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-transform-modules-commonjs@npm:^7.25.9":
+ version: 7.26.3
+ resolution: "@babel/plugin-transform-modules-commonjs@npm:7.26.3"
+ dependencies:
+ "@babel/helper-module-transforms": "npm:^7.26.0"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10/f817f02fa04d13f1578f3026239b57f1003bebcf9f9b8d854714bed76a0e4986c79bd6d2e0ac14282c5d309454a8dab683c179709ca753b0152a69c69f3a78e3
+ languageName: node
+ linkType: hard
+
"@babel/plugin-transform-modules-systemjs@npm:^7.23.9":
version: 7.23.9
resolution: "@babel/plugin-transform-modules-systemjs@npm:7.23.9"
@@ -2187,6 +2807,20 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-transform-modules-systemjs@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-modules-systemjs@npm:7.25.9"
+ dependencies:
+ "@babel/helper-module-transforms": "npm:^7.25.9"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ "@babel/helper-validator-identifier": "npm:^7.25.9"
+ "@babel/traverse": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10/03145aa89b7c867941a03755216cfb503df6d475a78df84849a157fa5f2fcc17ba114a968d0579ae34e7c61403f35d1ba5d188fdfb9ad05f19354eb7605792f9
+ languageName: node
+ linkType: hard
+
"@babel/plugin-transform-modules-umd@npm:^7.23.3":
version: 7.23.3
resolution: "@babel/plugin-transform-modules-umd@npm:7.23.3"
@@ -2211,6 +2845,18 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-transform-modules-umd@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-modules-umd@npm:7.25.9"
+ dependencies:
+ "@babel/helper-module-transforms": "npm:^7.25.9"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10/47d03485fedac828832d9fee33b3b982a6db8197e8651ceb5d001890e276150b5a7ee3e9780749e1ba76453c471af907a159108832c24f93453dd45221788e97
+ languageName: node
+ linkType: hard
+
"@babel/plugin-transform-named-capturing-groups-regex@npm:^7.0.0, @babel/plugin-transform-named-capturing-groups-regex@npm:^7.22.5":
version: 7.22.5
resolution: "@babel/plugin-transform-named-capturing-groups-regex@npm:7.22.5"
@@ -2235,6 +2881,18 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-transform-named-capturing-groups-regex@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-named-capturing-groups-regex@npm:7.25.9"
+ dependencies:
+ "@babel/helper-create-regexp-features-plugin": "npm:^7.25.9"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0
+ checksum: 10/434346ba05cf74e3f4704b3bdd439287b95cd2a8676afcdc607810b8c38b6f4798cd69c1419726b2e4c7204e62e4a04d31b0360e91ca57a930521c9211e07789
+ languageName: node
+ linkType: hard
+
"@babel/plugin-transform-new-target@npm:^7.23.3":
version: 7.23.3
resolution: "@babel/plugin-transform-new-target@npm:7.23.3"
@@ -2257,6 +2915,17 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-transform-new-target@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-new-target@npm:7.25.9"
+ dependencies:
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10/07bb3a09028ee7b8e8ede6e6390e3b3aecc5cf9adb2fc5475ff58036c552b8a3f8e63d4c43211a60545f3307cdc15919f0e54cb5455d9546daed162dc54ff94e
+ languageName: node
+ linkType: hard
+
"@babel/plugin-transform-nullish-coalescing-operator@npm:^7.23.4":
version: 7.23.4
resolution: "@babel/plugin-transform-nullish-coalescing-operator@npm:7.23.4"
@@ -2281,6 +2950,17 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-transform-nullish-coalescing-operator@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-nullish-coalescing-operator@npm:7.25.9"
+ dependencies:
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10/26e03b1c2c0408cc300e46d8f8cb639653ff3a7b03456d0d8afbb53c44f33a89323f51d99991dade3a5676921119bbdf869728bb7911799b5ef99ffafa2cdd24
+ languageName: node
+ linkType: hard
+
"@babel/plugin-transform-numeric-separator@npm:^7.23.4":
version: 7.23.4
resolution: "@babel/plugin-transform-numeric-separator@npm:7.23.4"
@@ -2305,6 +2985,17 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-transform-numeric-separator@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-numeric-separator@npm:7.25.9"
+ dependencies:
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10/0528ef041ed88e8c3f51624ee87b8182a7f246fe4013f0572788e0727d20795b558f2b82e3989b5dd416cbd339500f0d88857de41b6d3b6fdacb1d5344bcc5b1
+ languageName: node
+ linkType: hard
+
"@babel/plugin-transform-object-rest-spread@npm:^7.12.13":
version: 7.24.1
resolution: "@babel/plugin-transform-object-rest-spread@npm:7.24.1"
@@ -2348,6 +3039,19 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-transform-object-rest-spread@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-object-rest-spread@npm:7.25.9"
+ dependencies:
+ "@babel/helper-compilation-targets": "npm:^7.25.9"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ "@babel/plugin-transform-parameters": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10/a157ac5af2721090150858f301d9c0a3a0efb8ef66b90fce326d6cc0ae45ab97b6219b3e441bf8d72a2287e95eb04dd6c12544da88ea2345e70b3fac2c0ac9e2
+ languageName: node
+ linkType: hard
+
"@babel/plugin-transform-object-super@npm:^7.0.0":
version: 7.24.1
resolution: "@babel/plugin-transform-object-super@npm:7.24.1"
@@ -2384,6 +3088,18 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-transform-object-super@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-object-super@npm:7.25.9"
+ dependencies:
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ "@babel/helper-replace-supers": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10/1817b5d8b80e451ae1ad9080cca884f4f16df75880a158947df76a2ed8ab404d567a7dce71dd8051ef95f90fbe3513154086a32aba55cc76027f6cbabfbd7f98
+ languageName: node
+ linkType: hard
+
"@babel/plugin-transform-optional-catch-binding@npm:^7.23.4":
version: 7.23.4
resolution: "@babel/plugin-transform-optional-catch-binding@npm:7.23.4"
@@ -2400,11 +3116,22 @@ __metadata:
version: 7.24.7
resolution: "@babel/plugin-transform-optional-catch-binding@npm:7.24.7"
dependencies:
- "@babel/helper-plugin-utils": "npm:^7.24.7"
- "@babel/plugin-syntax-optional-catch-binding": "npm:^7.8.3"
+ "@babel/helper-plugin-utils": "npm:^7.24.7"
+ "@babel/plugin-syntax-optional-catch-binding": "npm:^7.8.3"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10/605ae3764354e83f73c1e6430bac29e308806abcce8d1369cf69e4921771ff3592e8f60ba60c15990070d79b8d8740f0841069d64b466b3ce8a8c43e9743da7e
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-transform-optional-catch-binding@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-optional-catch-binding@npm:7.25.9"
+ dependencies:
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: 10/605ae3764354e83f73c1e6430bac29e308806abcce8d1369cf69e4921771ff3592e8f60ba60c15990070d79b8d8740f0841069d64b466b3ce8a8c43e9743da7e
+ checksum: 10/b46a8d1e91829f3db5c252583eb00d05a779b4660abeea5500fda0f8ffa3584fd18299443c22f7fddf0ed9dfdb73c782c43b445dc468d4f89803f2356963b406
languageName: node
linkType: hard
@@ -2447,6 +3174,18 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-transform-optional-chaining@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-optional-chaining@npm:7.25.9"
+ dependencies:
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10/bc838a499fd9892e163b8bc9bfbc4bf0b28cc3232ee0a6406ae078257c8096518f871d09b4a32c11f4a2d6953c3bc1984619ef748f7ad45aed0b0d9689a8eb36
+ languageName: node
+ linkType: hard
+
"@babel/plugin-transform-parameters@npm:^7.0.0, @babel/plugin-transform-parameters@npm:^7.20.7, @babel/plugin-transform-parameters@npm:^7.23.3":
version: 7.23.3
resolution: "@babel/plugin-transform-parameters@npm:7.23.3"
@@ -2480,6 +3219,17 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-transform-parameters@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-parameters@npm:7.25.9"
+ dependencies:
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10/014009a1763deb41fe9f0dbca2c4489ce0ac83dd87395f488492e8eb52399f6c883d5bd591bae3b8836f2460c3937fcebd07e57dce1e0bfe30cdbc63fdfc9d3a
+ languageName: node
+ linkType: hard
+
"@babel/plugin-transform-private-methods@npm:^7.22.5, @babel/plugin-transform-private-methods@npm:^7.23.3":
version: 7.23.3
resolution: "@babel/plugin-transform-private-methods@npm:7.23.3"
@@ -2504,6 +3254,18 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-transform-private-methods@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-private-methods@npm:7.25.9"
+ dependencies:
+ "@babel/helper-create-class-features-plugin": "npm:^7.25.9"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10/6e3671b352c267847c53a170a1937210fa8151764d70d25005e711ef9b21969aaf422acc14f9f7fb86bc0e4ec43e7aefcc0ad9196ae02d262ec10f509f126a58
+ languageName: node
+ linkType: hard
+
"@babel/plugin-transform-private-property-in-object@npm:^7.22.11, @babel/plugin-transform-private-property-in-object@npm:^7.23.4":
version: 7.23.4
resolution: "@babel/plugin-transform-private-property-in-object@npm:7.23.4"
@@ -2532,6 +3294,19 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-transform-private-property-in-object@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-private-property-in-object@npm:7.25.9"
+ dependencies:
+ "@babel/helper-annotate-as-pure": "npm:^7.25.9"
+ "@babel/helper-create-class-features-plugin": "npm:^7.25.9"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10/aa45bb5669b610afa763d774a4b5583bb60ce7d38e4fd2dedfd0703e73e25aa560e6c6124e155aa90b101601743b127d9e5d3eb00989a7e4b4ab9c2eb88475ba
+ languageName: node
+ linkType: hard
+
"@babel/plugin-transform-property-literals@npm:^7.0.0":
version: 7.24.1
resolution: "@babel/plugin-transform-property-literals@npm:7.24.1"
@@ -2565,6 +3340,17 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-transform-property-literals@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-property-literals@npm:7.25.9"
+ dependencies:
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10/436046ab07d54a9b44a384eeffec701d4e959a37a7547dda72e069e751ca7ff753d1782a8339e354b97c78a868b49ea97bf41bf5a44c6d7a3c0a05ad40eeb49c
+ languageName: node
+ linkType: hard
+
"@babel/plugin-transform-react-display-name@npm:^7.0.0":
version: 7.23.3
resolution: "@babel/plugin-transform-react-display-name@npm:7.23.3"
@@ -2587,6 +3373,17 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-transform-react-display-name@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-react-display-name@npm:7.25.9"
+ dependencies:
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10/dc7affde0ed98e40f629ee92a2fc44fbd8008aabda1ddb3f5bd2632699d3289b08dff65b26cf3b89dab46397ec440f453d19856bbb3a9a83df5b4ac6157c5c39
+ languageName: node
+ linkType: hard
+
"@babel/plugin-transform-react-jsx-development@npm:^7.22.5":
version: 7.22.5
resolution: "@babel/plugin-transform-react-jsx-development@npm:7.22.5"
@@ -2598,6 +3395,17 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-transform-react-jsx-development@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-react-jsx-development@npm:7.25.9"
+ dependencies:
+ "@babel/plugin-transform-react-jsx": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10/537d38369537f1eb56041c4b770bc0733fde1801a7f5ffef40a1217ea448f33ee2fa8e6098a58a82fd00e432c1b9426a66849496da419020c9eca3b1b1a23779
+ languageName: node
+ linkType: hard
+
"@babel/plugin-transform-react-jsx-self@npm:^7.0.0":
version: 7.23.3
resolution: "@babel/plugin-transform-react-jsx-self@npm:7.23.3"
@@ -2635,6 +3443,21 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-transform-react-jsx@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-react-jsx@npm:7.25.9"
+ dependencies:
+ "@babel/helper-annotate-as-pure": "npm:^7.25.9"
+ "@babel/helper-module-imports": "npm:^7.25.9"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ "@babel/plugin-syntax-jsx": "npm:^7.25.9"
+ "@babel/types": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10/eb179ecdf0ae19aed254105cf78fbac35f9983f51ed04b7b67c863a4820a70a879bd5da250ac518321f86df20eac010e53e3411c8750c386d51da30e4814bfb6
+ languageName: node
+ linkType: hard
+
"@babel/plugin-transform-react-pure-annotations@npm:^7.24.1":
version: 7.24.1
resolution: "@babel/plugin-transform-react-pure-annotations@npm:7.24.1"
@@ -2647,6 +3470,18 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-transform-react-pure-annotations@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-react-pure-annotations@npm:7.25.9"
+ dependencies:
+ "@babel/helper-annotate-as-pure": "npm:^7.25.9"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10/9995c0fc7c25d3aaaa0ce84233de02eab2564ea111d0813ec5baa538eb21520402879cc787ad1ad4c2061b99cebc3beb09910e64c9592e8ccb42ae62d9e4fd9a
+ languageName: node
+ linkType: hard
+
"@babel/plugin-transform-regenerator@npm:^7.23.3":
version: 7.23.3
resolution: "@babel/plugin-transform-regenerator@npm:7.23.3"
@@ -2671,6 +3506,30 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-transform-regenerator@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-regenerator@npm:7.25.9"
+ dependencies:
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ regenerator-transform: "npm:^0.15.2"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10/1c09e8087b476c5967282c9790fb8710e065eda77c60f6cb5da541edd59ded9d003d96f8ef640928faab4a0b35bf997673499a194973da4f0c97f0935807a482
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-transform-regexp-modifiers@npm:^7.26.0":
+ version: 7.26.0
+ resolution: "@babel/plugin-transform-regexp-modifiers@npm:7.26.0"
+ dependencies:
+ "@babel/helper-create-regexp-features-plugin": "npm:^7.25.9"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0
+ checksum: 10/726deca486bbd4b176f8a966eb0f4aabc19d9def3b8dabb8b3a656778eca0df1fda3f3c92b213aa5a184232fdafd5b7bd73b4e24ca4345c498ef6baff2bda4e1
+ languageName: node
+ linkType: hard
+
"@babel/plugin-transform-reserved-words@npm:^7.23.3":
version: 7.23.3
resolution: "@babel/plugin-transform-reserved-words@npm:7.23.3"
@@ -2693,6 +3552,17 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-transform-reserved-words@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-reserved-words@npm:7.25.9"
+ dependencies:
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10/8beda04481b25767acbd1f6b9ef7b3a9c12fbd9dcb24df45a6ad120e1dc4b247c073db60ac742f9093657d6d8c050501fc0606af042f81a3bb6a3ff862cddc47
+ languageName: node
+ linkType: hard
+
"@babel/plugin-transform-runtime@npm:^7.0.0":
version: 7.23.9
resolution: "@babel/plugin-transform-runtime@npm:7.23.9"
@@ -2731,6 +3601,17 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-transform-shorthand-properties@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-shorthand-properties@npm:7.25.9"
+ dependencies:
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10/f774995d58d4e3a992b732cf3a9b8823552d471040e280264dd15e0735433d51b468fef04d75853d061309389c66bda10ce1b298297ce83999220eb0ad62741d
+ languageName: node
+ linkType: hard
+
"@babel/plugin-transform-spread@npm:^7.0.0, @babel/plugin-transform-spread@npm:^7.23.3":
version: 7.23.3
resolution: "@babel/plugin-transform-spread@npm:7.23.3"
@@ -2755,6 +3636,18 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-transform-spread@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-spread@npm:7.25.9"
+ dependencies:
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10/fe72c6545267176cdc9b6f32f30f9ced37c1cafa1290e4436b83b8f377b4f1c175dad404228c96e3efdec75da692f15bfb9db2108fcd9ad260bc9968778ee41e
+ languageName: node
+ linkType: hard
+
"@babel/plugin-transform-sticky-regex@npm:^7.0.0, @babel/plugin-transform-sticky-regex@npm:^7.23.3":
version: 7.23.3
resolution: "@babel/plugin-transform-sticky-regex@npm:7.23.3"
@@ -2777,6 +3670,28 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-transform-sticky-regex@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-sticky-regex@npm:7.25.9"
+ dependencies:
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10/7454b00844dbe924030dd15e2b3615b36e196500c4c47e98dabc6b37a054c5b1038ecd437e910aabf0e43bf56b973cb148d3437d50f6e2332d8309568e3e979b
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-transform-strict-mode@npm:^7.24.7":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-strict-mode@npm:7.25.9"
+ dependencies:
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10/87b4a937b7c6f9cc4ed557ce1e2037898ec9c2af18f5523a5200f714cfd4101b0e278c732418b59a779e912cdf5574e35db01714d5b4e6fff2e31584501e4364
+ languageName: node
+ linkType: hard
+
"@babel/plugin-transform-template-literals@npm:^7.0.0":
version: 7.24.1
resolution: "@babel/plugin-transform-template-literals@npm:7.24.1"
@@ -2810,6 +3725,17 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-transform-template-literals@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-template-literals@npm:7.25.9"
+ dependencies:
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10/92eb1d6e2d95bd24abbb74fa7640d02b66ff6214e0bb616d7fda298a7821ce15132a4265d576a3502a347a3c9e94b6c69ed265bb0784664592fa076785a3d16a
+ languageName: node
+ linkType: hard
+
"@babel/plugin-transform-typeof-symbol@npm:^7.23.3":
version: 7.23.3
resolution: "@babel/plugin-transform-typeof-symbol@npm:7.23.3"
@@ -2832,6 +3758,17 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-transform-typeof-symbol@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-typeof-symbol@npm:7.25.9"
+ dependencies:
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10/3ae240358f0b0cd59f8610d6c59d395c216fd1bab407f7de58b86d592f030fb42b4d18e2456a29bee4a2ff014c4c1e3404c8ae64462b1155d1c053b2f9d73438
+ languageName: node
+ linkType: hard
+
"@babel/plugin-transform-typescript@npm:^7.23.3, @babel/plugin-transform-typescript@npm:^7.5.0":
version: 7.23.6
resolution: "@babel/plugin-transform-typescript@npm:7.23.6"
@@ -2846,6 +3783,21 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-transform-typescript@npm:^7.25.9":
+ version: 7.26.3
+ resolution: "@babel/plugin-transform-typescript@npm:7.26.3"
+ dependencies:
+ "@babel/helper-annotate-as-pure": "npm:^7.25.9"
+ "@babel/helper-create-class-features-plugin": "npm:^7.25.9"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.25.9"
+ "@babel/plugin-syntax-typescript": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10/71e82045fc931112ca6cba1826a7d521a30514ea5e8370c3c083f6ee1ed624d62d91e1415fbc41ce9033c4e78ba638a904c43b2d7e023873f36675844b8a4963
+ languageName: node
+ linkType: hard
+
"@babel/plugin-transform-unicode-escapes@npm:^7.23.3":
version: 7.23.3
resolution: "@babel/plugin-transform-unicode-escapes@npm:7.23.3"
@@ -2868,6 +3820,17 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-transform-unicode-escapes@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-unicode-escapes@npm:7.25.9"
+ dependencies:
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10/f138cbee539963fb3da13f684e6f33c9f7495220369ae12a682b358f1e25ac68936825562c38eae87f01ac9992b2129208b35ec18533567fc805ce5ed0ffd775
+ languageName: node
+ linkType: hard
+
"@babel/plugin-transform-unicode-property-regex@npm:^7.23.3":
version: 7.23.3
resolution: "@babel/plugin-transform-unicode-property-regex@npm:7.23.3"
@@ -2892,6 +3855,18 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-transform-unicode-property-regex@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-unicode-property-regex@npm:7.25.9"
+ dependencies:
+ "@babel/helper-create-regexp-features-plugin": "npm:^7.25.9"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10/201f6f46c1beb399e79aa208b94c5d54412047511795ce1e790edcd189cef73752e6a099fdfc01b3ad12205f139ae344143b62f21f44bbe02338a95e8506a911
+ languageName: node
+ linkType: hard
+
"@babel/plugin-transform-unicode-regex@npm:^7.0.0, @babel/plugin-transform-unicode-regex@npm:^7.23.3":
version: 7.23.3
resolution: "@babel/plugin-transform-unicode-regex@npm:7.23.3"
@@ -2916,6 +3891,18 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-transform-unicode-regex@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-unicode-regex@npm:7.25.9"
+ dependencies:
+ "@babel/helper-create-regexp-features-plugin": "npm:^7.25.9"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10/e8baae867526e179467c6ef5280d70390fa7388f8763a19a27c21302dd59b121032568be080749514b097097ceb9af716bf4b90638f1b3cf689aa837ba20150f
+ languageName: node
+ linkType: hard
+
"@babel/plugin-transform-unicode-sets-regex@npm:^7.23.3":
version: 7.23.3
resolution: "@babel/plugin-transform-unicode-sets-regex@npm:7.23.3"
@@ -2940,6 +3927,18 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-transform-unicode-sets-regex@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/plugin-transform-unicode-sets-regex@npm:7.25.9"
+ dependencies:
+ "@babel/helper-create-regexp-features-plugin": "npm:^7.25.9"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0
+ checksum: 10/4445ef20de687cb4dcc95169742a8d9013d680aa5eee9186d8e25875bbfa7ee5e2de26a91177ccf70b1db518e36886abcd44750d28db5d7a9539f0efa6839f4b
+ languageName: node
+ linkType: hard
+
"@babel/preset-env@npm:^7.20.0":
version: 7.23.9
resolution: "@babel/preset-env@npm:7.23.9"
@@ -3030,6 +4029,85 @@ __metadata:
languageName: node
linkType: hard
+"@babel/preset-env@npm:^7.25.2":
+ version: 7.26.0
+ resolution: "@babel/preset-env@npm:7.26.0"
+ dependencies:
+ "@babel/compat-data": "npm:^7.26.0"
+ "@babel/helper-compilation-targets": "npm:^7.25.9"
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ "@babel/helper-validator-option": "npm:^7.25.9"
+ "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "npm:^7.25.9"
+ "@babel/plugin-bugfix-safari-class-field-initializer-scope": "npm:^7.25.9"
+ "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "npm:^7.25.9"
+ "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "npm:^7.25.9"
+ "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "npm:^7.25.9"
+ "@babel/plugin-proposal-private-property-in-object": "npm:7.21.0-placeholder-for-preset-env.2"
+ "@babel/plugin-syntax-import-assertions": "npm:^7.26.0"
+ "@babel/plugin-syntax-import-attributes": "npm:^7.26.0"
+ "@babel/plugin-syntax-unicode-sets-regex": "npm:^7.18.6"
+ "@babel/plugin-transform-arrow-functions": "npm:^7.25.9"
+ "@babel/plugin-transform-async-generator-functions": "npm:^7.25.9"
+ "@babel/plugin-transform-async-to-generator": "npm:^7.25.9"
+ "@babel/plugin-transform-block-scoped-functions": "npm:^7.25.9"
+ "@babel/plugin-transform-block-scoping": "npm:^7.25.9"
+ "@babel/plugin-transform-class-properties": "npm:^7.25.9"
+ "@babel/plugin-transform-class-static-block": "npm:^7.26.0"
+ "@babel/plugin-transform-classes": "npm:^7.25.9"
+ "@babel/plugin-transform-computed-properties": "npm:^7.25.9"
+ "@babel/plugin-transform-destructuring": "npm:^7.25.9"
+ "@babel/plugin-transform-dotall-regex": "npm:^7.25.9"
+ "@babel/plugin-transform-duplicate-keys": "npm:^7.25.9"
+ "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "npm:^7.25.9"
+ "@babel/plugin-transform-dynamic-import": "npm:^7.25.9"
+ "@babel/plugin-transform-exponentiation-operator": "npm:^7.25.9"
+ "@babel/plugin-transform-export-namespace-from": "npm:^7.25.9"
+ "@babel/plugin-transform-for-of": "npm:^7.25.9"
+ "@babel/plugin-transform-function-name": "npm:^7.25.9"
+ "@babel/plugin-transform-json-strings": "npm:^7.25.9"
+ "@babel/plugin-transform-literals": "npm:^7.25.9"
+ "@babel/plugin-transform-logical-assignment-operators": "npm:^7.25.9"
+ "@babel/plugin-transform-member-expression-literals": "npm:^7.25.9"
+ "@babel/plugin-transform-modules-amd": "npm:^7.25.9"
+ "@babel/plugin-transform-modules-commonjs": "npm:^7.25.9"
+ "@babel/plugin-transform-modules-systemjs": "npm:^7.25.9"
+ "@babel/plugin-transform-modules-umd": "npm:^7.25.9"
+ "@babel/plugin-transform-named-capturing-groups-regex": "npm:^7.25.9"
+ "@babel/plugin-transform-new-target": "npm:^7.25.9"
+ "@babel/plugin-transform-nullish-coalescing-operator": "npm:^7.25.9"
+ "@babel/plugin-transform-numeric-separator": "npm:^7.25.9"
+ "@babel/plugin-transform-object-rest-spread": "npm:^7.25.9"
+ "@babel/plugin-transform-object-super": "npm:^7.25.9"
+ "@babel/plugin-transform-optional-catch-binding": "npm:^7.25.9"
+ "@babel/plugin-transform-optional-chaining": "npm:^7.25.9"
+ "@babel/plugin-transform-parameters": "npm:^7.25.9"
+ "@babel/plugin-transform-private-methods": "npm:^7.25.9"
+ "@babel/plugin-transform-private-property-in-object": "npm:^7.25.9"
+ "@babel/plugin-transform-property-literals": "npm:^7.25.9"
+ "@babel/plugin-transform-regenerator": "npm:^7.25.9"
+ "@babel/plugin-transform-regexp-modifiers": "npm:^7.26.0"
+ "@babel/plugin-transform-reserved-words": "npm:^7.25.9"
+ "@babel/plugin-transform-shorthand-properties": "npm:^7.25.9"
+ "@babel/plugin-transform-spread": "npm:^7.25.9"
+ "@babel/plugin-transform-sticky-regex": "npm:^7.25.9"
+ "@babel/plugin-transform-template-literals": "npm:^7.25.9"
+ "@babel/plugin-transform-typeof-symbol": "npm:^7.25.9"
+ "@babel/plugin-transform-unicode-escapes": "npm:^7.25.9"
+ "@babel/plugin-transform-unicode-property-regex": "npm:^7.25.9"
+ "@babel/plugin-transform-unicode-regex": "npm:^7.25.9"
+ "@babel/plugin-transform-unicode-sets-regex": "npm:^7.25.9"
+ "@babel/preset-modules": "npm:0.1.6-no-external-plugins"
+ babel-plugin-polyfill-corejs2: "npm:^0.4.10"
+ babel-plugin-polyfill-corejs3: "npm:^0.10.6"
+ babel-plugin-polyfill-regenerator: "npm:^0.6.1"
+ core-js-compat: "npm:^3.38.1"
+ semver: "npm:^6.3.1"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10/a7a80314f845deea713985a6316361c476621c76cfe5c6c28e8b9558f01634b49bbfdd3581ef94b5d6cff5c2b8830468aa53a73f5b5c1224db2dfea5db7e676f
+ languageName: node
+ linkType: hard
+
"@babel/preset-env@npm:^7.25.4":
version: 7.25.4
resolution: "@babel/preset-env@npm:7.25.4"
@@ -3136,6 +4214,19 @@ __metadata:
languageName: node
linkType: hard
+"@babel/preset-flow@npm:^7.24.7":
+ version: 7.25.9
+ resolution: "@babel/preset-flow@npm:7.25.9"
+ dependencies:
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ "@babel/helper-validator-option": "npm:^7.25.9"
+ "@babel/plugin-transform-flow-strip-types": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10/b1591ea63a7ace7e34bcefa6deba9e2814d7f082e3c074e2648efb68a1a49016ccefbea024156ba28bd3042a4e768e3eb8b5ecfe433978144fdaaadd36203ba2
+ languageName: node
+ linkType: hard
+
"@babel/preset-modules@npm:0.1.6-no-external-plugins":
version: 0.1.6-no-external-plugins
resolution: "@babel/preset-modules@npm:0.1.6-no-external-plugins"
@@ -3165,6 +4256,22 @@ __metadata:
languageName: node
linkType: hard
+"@babel/preset-react@npm:^7.24.7":
+ version: 7.26.3
+ resolution: "@babel/preset-react@npm:7.26.3"
+ dependencies:
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ "@babel/helper-validator-option": "npm:^7.25.9"
+ "@babel/plugin-transform-react-display-name": "npm:^7.25.9"
+ "@babel/plugin-transform-react-jsx": "npm:^7.25.9"
+ "@babel/plugin-transform-react-jsx-development": "npm:^7.25.9"
+ "@babel/plugin-transform-react-pure-annotations": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10/88cb78c402b79f32389ee06451da51698d5b1da7641d9a47482883f537fe5441a138bd4c077d8533fd6d557406b08911c47b94402cea843db598e020bdd9a373
+ languageName: node
+ linkType: hard
+
"@babel/preset-typescript@npm:^7.13.0":
version: 7.23.3
resolution: "@babel/preset-typescript@npm:7.23.3"
@@ -3180,6 +4287,21 @@ __metadata:
languageName: node
linkType: hard
+"@babel/preset-typescript@npm:^7.24.7":
+ version: 7.26.0
+ resolution: "@babel/preset-typescript@npm:7.26.0"
+ dependencies:
+ "@babel/helper-plugin-utils": "npm:^7.25.9"
+ "@babel/helper-validator-option": "npm:^7.25.9"
+ "@babel/plugin-syntax-jsx": "npm:^7.25.9"
+ "@babel/plugin-transform-modules-commonjs": "npm:^7.25.9"
+ "@babel/plugin-transform-typescript": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10/81a60826160163a3daae017709f42147744757b725b50c9024ef3ee5a402ee45fd2e93eaecdaaa22c81be91f7940916249cfb7711366431cfcacc69c95878c03
+ languageName: node
+ linkType: hard
+
"@babel/register@npm:^7.13.16":
version: 7.23.7
resolution: "@babel/register@npm:7.23.7"
@@ -3211,6 +4333,15 @@ __metadata:
languageName: node
linkType: hard
+"@babel/runtime@npm:^7.25.0":
+ version: 7.26.0
+ resolution: "@babel/runtime@npm:7.26.0"
+ dependencies:
+ regenerator-runtime: "npm:^0.14.0"
+ checksum: 10/9f4ea1c1d566c497c052d505587554e782e021e6ccd302c2ad7ae8291c8e16e3f19d4a7726fb64469e057779ea2081c28b7dbefec6d813a22f08a35712c0f699
+ languageName: node
+ linkType: hard
+
"@babel/template@npm:^7.0.0, @babel/template@npm:^7.22.15, @babel/template@npm:^7.23.9, @babel/template@npm:^7.3.3":
version: 7.23.9
resolution: "@babel/template@npm:7.23.9"
@@ -3244,6 +4375,17 @@ __metadata:
languageName: node
linkType: hard
+"@babel/template@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/template@npm:7.25.9"
+ dependencies:
+ "@babel/code-frame": "npm:^7.25.9"
+ "@babel/parser": "npm:^7.25.9"
+ "@babel/types": "npm:^7.25.9"
+ checksum: 10/e861180881507210150c1335ad94aff80fd9e9be6202e1efa752059c93224e2d5310186ddcdd4c0f0b0fc658ce48cb47823f15142b5c00c8456dde54f5de80b2
+ languageName: node
+ linkType: hard
+
"@babel/traverse@npm:^7.20.0, @babel/traverse@npm:^7.23.9":
version: 7.23.9
resolution: "@babel/traverse@npm:7.23.9"
@@ -3295,6 +4437,21 @@ __metadata:
languageName: node
linkType: hard
+"@babel/traverse@npm:^7.25.9":
+ version: 7.26.4
+ resolution: "@babel/traverse@npm:7.26.4"
+ dependencies:
+ "@babel/code-frame": "npm:^7.26.2"
+ "@babel/generator": "npm:^7.26.3"
+ "@babel/parser": "npm:^7.26.3"
+ "@babel/template": "npm:^7.25.9"
+ "@babel/types": "npm:^7.26.3"
+ debug: "npm:^4.3.1"
+ globals: "npm:^11.1.0"
+ checksum: 10/30c81a80d66fc39842814bc2e847f4705d30f3859156f130d90a0334fe1d53aa81eed877320141a528ecbc36448acc0f14f544a7d410fa319d1c3ab63b50b58f
+ languageName: node
+ linkType: hard
+
"@babel/types@npm:^7.0.0, @babel/types@npm:^7.20.0, @babel/types@npm:^7.20.7, @babel/types@npm:^7.22.15, @babel/types@npm:^7.22.19, @babel/types@npm:^7.22.5, @babel/types@npm:^7.23.0, @babel/types@npm:^7.23.4, @babel/types@npm:^7.23.6, @babel/types@npm:^7.23.9, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4, @babel/types@npm:^7.8.3":
version: 7.23.9
resolution: "@babel/types@npm:7.23.9"
@@ -3339,6 +4496,16 @@ __metadata:
languageName: node
linkType: hard
+"@babel/types@npm:^7.25.9, @babel/types@npm:^7.26.3":
+ version: 7.26.3
+ resolution: "@babel/types@npm:7.26.3"
+ dependencies:
+ "@babel/helper-string-parser": "npm:^7.25.9"
+ "@babel/helper-validator-identifier": "npm:^7.25.9"
+ checksum: 10/c31d0549630a89abfa11410bf82a318b0c87aa846fbf5f9905e47ba5e2aa44f41cc746442f105d622c519e4dc532d35a8d8080460ff4692f9fc7485fbf3a00eb
+ languageName: node
+ linkType: hard
+
"@bcoe/v8-coverage@npm:^0.2.3":
version: 0.2.3
resolution: "@bcoe/v8-coverage@npm:0.2.3"
@@ -6402,6 +7569,16 @@ __metadata:
languageName: unknown
linkType: soft
+"@react-native-firebase/vertexai@npm:0.0.1, @react-native-firebase/vertexai@workspace:packages/vertexai":
+ version: 0.0.0-use.local
+ resolution: "@react-native-firebase/vertexai@workspace:packages/vertexai"
+ dependencies:
+ react-native-builder-bob: "npm:^0.35.2"
+ peerDependencies:
+ "@react-native-firebase/app": 21.6.2
+ languageName: unknown
+ linkType: soft
+
"@react-native-mac/virtualized-lists@npm:0.74.87":
version: 0.74.87
resolution: "@react-native-mac/virtualized-lists@npm:0.74.87"
@@ -8230,6 +9407,19 @@ __metadata:
languageName: node
linkType: hard
+"babel-plugin-module-resolver@npm:^5.0.2":
+ version: 5.0.2
+ resolution: "babel-plugin-module-resolver@npm:5.0.2"
+ dependencies:
+ find-babel-config: "npm:^2.1.1"
+ glob: "npm:^9.3.3"
+ pkg-up: "npm:^3.1.0"
+ reselect: "npm:^4.1.7"
+ resolve: "npm:^1.22.8"
+ checksum: 10/8084fa8a4cd96aaa861e5fe765a6cd03accef64d21d4108e314029bcd5f3a7fd96faf0c877c575a6a24d4fe0d87458d49748ca56faa4c77b2b812e4ed6023768
+ languageName: node
+ linkType: hard
+
"babel-plugin-polyfill-corejs2@npm:^0.4.10":
version: 0.4.10
resolution: "babel-plugin-polyfill-corejs2@npm:0.4.10"
@@ -8661,6 +9851,20 @@ __metadata:
languageName: node
linkType: hard
+"browserslist@npm:^4.20.4, browserslist@npm:^4.24.0, browserslist@npm:^4.24.3":
+ version: 4.24.4
+ resolution: "browserslist@npm:4.24.4"
+ dependencies:
+ caniuse-lite: "npm:^1.0.30001688"
+ electron-to-chromium: "npm:^1.5.73"
+ node-releases: "npm:^2.0.19"
+ update-browserslist-db: "npm:^1.1.1"
+ bin:
+ browserslist: cli.js
+ checksum: 10/11fda105e803d891311a21a1f962d83599319165faf471c2d70e045dff82a12128f5b50b1fcba665a2352ad66147aaa248a9d2355a80aadc3f53375eb3de2e48
+ languageName: node
+ linkType: hard
+
"browserslist@npm:^4.22.2, browserslist@npm:^4.22.3":
version: 4.23.0
resolution: "browserslist@npm:4.23.0"
@@ -9063,6 +10267,13 @@ __metadata:
languageName: node
linkType: hard
+"caniuse-lite@npm:^1.0.30001688":
+ version: 1.0.30001690
+ resolution: "caniuse-lite@npm:1.0.30001690"
+ checksum: 10/9fb4659eb09a298601b9593739072c481e2f5cc524bd0530e5e0f002e66246da5e866669854dfc0d53195ee36b201dab02f7933a7cdf60ccba7adb2d4a304caf
+ languageName: node
+ linkType: hard
+
"ccount@npm:^2.0.0":
version: 2.0.1
resolution: "ccount@npm:2.0.1"
@@ -10059,6 +11270,15 @@ __metadata:
languageName: node
linkType: hard
+"core-js-compat@npm:^3.38.1":
+ version: 3.40.0
+ resolution: "core-js-compat@npm:3.40.0"
+ dependencies:
+ browserslist: "npm:^4.24.3"
+ checksum: 10/3dd3d717b3d4ae0d9c2930d39c0f2a21ca6f195fcdd5711bda833557996c4d9f90277eab576423478e95689257e2de8d1a2623d6618084416bd224d10d5df9a4
+ languageName: node
+ linkType: hard
+
"core-util-is@npm:~1.0.0":
version: 1.0.3
resolution: "core-util-is@npm:1.0.3"
@@ -10450,6 +11670,13 @@ __metadata:
languageName: node
linkType: hard
+"dedent@npm:^0.7.0":
+ version: 0.7.0
+ resolution: "dedent@npm:0.7.0"
+ checksum: 10/87de191050d9a40dd70cad01159a0bcf05ecb59750951242070b6abf9569088684880d00ba92a955b4058804f16eeaf91d604f283929b4f614d181cd7ae633d2
+ languageName: node
+ linkType: hard
+
"dedent@npm:^1.0.0":
version: 1.5.1
resolution: "dedent@npm:1.5.1"
@@ -10568,7 +11795,7 @@ __metadata:
languageName: node
linkType: hard
-"del@npm:^6.0.0":
+"del@npm:^6.0.0, del@npm:^6.1.1":
version: 6.1.1
resolution: "del@npm:6.1.1"
dependencies:
@@ -10958,6 +12185,13 @@ __metadata:
languageName: node
linkType: hard
+"electron-to-chromium@npm:^1.5.73":
+ version: 1.5.79
+ resolution: "electron-to-chromium@npm:1.5.79"
+ checksum: 10/c5b25ba04b4f4b46c4024b96e00e43adcd6c321b48c74c8d2660f69704901da5a6592009cbf96c36c89e3f6b53d7742e2b89514477fddbccf4e5c4caebed9d49
+ languageName: node
+ linkType: hard
+
"emittery@npm:^0.13.1":
version: 0.13.1
resolution: "emittery@npm:0.13.1"
@@ -11317,7 +12551,7 @@ __metadata:
languageName: node
linkType: hard
-"escalade@npm:^3.1.2":
+"escalade@npm:^3.1.2, escalade@npm:^3.2.0":
version: 3.2.0
resolution: "escalade@npm:3.2.0"
checksum: 10/9d7169e3965b2f9ae46971afa392f6e5a25545ea30f2e2dd99c9b0a95a3f52b5653681a84f5b2911a413ddad2d7a93d3514165072f349b5ffc59c75a899970d6
@@ -11666,6 +12900,23 @@ __metadata:
languageName: node
linkType: hard
+"execa@npm:^4.0.3":
+ version: 4.1.0
+ resolution: "execa@npm:4.1.0"
+ dependencies:
+ cross-spawn: "npm:^7.0.0"
+ get-stream: "npm:^5.0.0"
+ human-signals: "npm:^1.1.1"
+ is-stream: "npm:^2.0.0"
+ merge-stream: "npm:^2.0.0"
+ npm-run-path: "npm:^4.0.0"
+ onetime: "npm:^5.1.0"
+ signal-exit: "npm:^3.0.2"
+ strip-final-newline: "npm:^2.0.0"
+ checksum: 10/ed58e41fe424797f3d837c8fb622548eeb72fa03324f2676af95f806568904eb55f196127a097f87d4517cab524c169ece13e6c9e201867de57b089584864b8f
+ languageName: node
+ linkType: hard
+
"execa@npm:^5.0.0, execa@npm:^5.1.1":
version: 5.1.1
resolution: "execa@npm:5.1.1"
@@ -12182,6 +13433,15 @@ __metadata:
languageName: node
linkType: hard
+"find-babel-config@npm:^2.1.1":
+ version: 2.1.2
+ resolution: "find-babel-config@npm:2.1.2"
+ dependencies:
+ json5: "npm:^2.2.3"
+ checksum: 10/f0fae1a9125a379cf660fc1b5ca7c1fc1edac5f47e521a89e4c2b92865c8e57101a9152ee503eef9f33e16f196182f2cff03d7768b7caf5eef81c80f1c124a2f
+ languageName: node
+ linkType: hard
+
"find-cache-dir@npm:^2.0.0":
version: 2.1.0
resolution: "find-cache-dir@npm:2.1.0"
@@ -12885,6 +14145,15 @@ __metadata:
languageName: node
linkType: hard
+"get-stream@npm:^5.0.0":
+ version: 5.2.0
+ resolution: "get-stream@npm:5.2.0"
+ dependencies:
+ pump: "npm:^3.0.0"
+ checksum: 10/13a73148dca795e41421013da6e3ebff8ccb7fba4d2f023fd0c6da2c166ec4e789bec9774a73a7b49c08daf2cae552f8a3e914042ac23b5f59dd278cc8f9cbfb
+ languageName: node
+ linkType: hard
+
"get-stream@npm:^6.0.0":
version: 6.0.1
resolution: "get-stream@npm:6.0.1"
@@ -13131,7 +14400,7 @@ __metadata:
languageName: node
linkType: hard
-"glob@npm:^9.2.0":
+"glob@npm:^9.2.0, glob@npm:^9.3.3":
version: 9.3.5
resolution: "glob@npm:9.3.5"
dependencies:
@@ -13488,6 +14757,13 @@ __metadata:
languageName: node
linkType: hard
+"hermes-estree@npm:0.23.1":
+ version: 0.23.1
+ resolution: "hermes-estree@npm:0.23.1"
+ checksum: 10/b7ad78f53044d53ec1c77e93036c16e34f6f0985c895540876301e4791d4db08da828870977140f5cf1ae34532bbb9d9d013a0a1a4a5a0da05177225648d5295
+ languageName: node
+ linkType: hard
+
"hermes-parser@npm:0.15.0":
version: 0.15.0
resolution: "hermes-parser@npm:0.15.0"
@@ -13506,6 +14782,15 @@ __metadata:
languageName: node
linkType: hard
+"hermes-parser@npm:0.23.1":
+ version: 0.23.1
+ resolution: "hermes-parser@npm:0.23.1"
+ dependencies:
+ hermes-estree: "npm:0.23.1"
+ checksum: 10/de88df4f23bd8dc2ffa89c8a317445320af8c7705a2aeeb05c4dd171f037a747982be153a0a237b1c9c7337b79bceaeb5052934cb8a25fe2e2473294a5343334
+ languageName: node
+ linkType: hard
+
"hermes-profile-transformer@npm:^0.0.6":
version: 0.0.6
resolution: "hermes-profile-transformer@npm:0.0.6"
@@ -13640,6 +14925,13 @@ __metadata:
languageName: node
linkType: hard
+"human-signals@npm:^1.1.1":
+ version: 1.1.1
+ resolution: "human-signals@npm:1.1.1"
+ checksum: 10/6a58224dffcef5588910b1028bda8623c9a7053460a1fe3367e61921a6b5f6b93aba30f323868a958f968d7de3f5f78421f11d4d9f7e9563b1bd2b00ed9a4deb
+ languageName: node
+ linkType: hard
+
"human-signals@npm:^2.1.0":
version: 2.1.0
resolution: "human-signals@npm:2.1.0"
@@ -13935,6 +15227,16 @@ __metadata:
languageName: node
linkType: hard
+"is-absolute@npm:^1.0.0":
+ version: 1.0.0
+ resolution: "is-absolute@npm:1.0.0"
+ dependencies:
+ is-relative: "npm:^1.0.0"
+ is-windows: "npm:^1.0.1"
+ checksum: 10/9d16b2605eda3f3ce755410f1d423e327ad3a898bcb86c9354cf63970ed3f91ba85e9828aa56f5d6a952b9fae43d0477770f78d37409ae8ecc31e59ebc279b27
+ languageName: node
+ linkType: hard
+
"is-arguments@npm:^1.0.4":
version: 1.1.1
resolution: "is-arguments@npm:1.1.1"
@@ -14145,6 +15447,26 @@ __metadata:
languageName: node
linkType: hard
+"is-git-dirty@npm:^2.0.1":
+ version: 2.0.2
+ resolution: "is-git-dirty@npm:2.0.2"
+ dependencies:
+ execa: "npm:^4.0.3"
+ is-git-repository: "npm:^2.0.0"
+ checksum: 10/13c8f58600e1ea0874703c1fa0ca87825119cf05347bb3b0bbbd331eec42b6a0e89519be4dcb173ac8eda84d1ade97fe187df8af10df599f1df8d0267680abdd
+ languageName: node
+ linkType: hard
+
+"is-git-repository@npm:^2.0.0":
+ version: 2.0.0
+ resolution: "is-git-repository@npm:2.0.0"
+ dependencies:
+ execa: "npm:^4.0.3"
+ is-absolute: "npm:^1.0.0"
+ checksum: 10/9eba76437998b3239adc6e87ceb9b81f8ef00d6209f8700f2ba523e61359d5b068d11f8f94474bc90f92b39fd3c8261c4d60feb3cd62d18e1838480b0b135b88
+ languageName: node
+ linkType: hard
+
"is-glob@npm:^2.0.0":
version: 2.0.1
resolution: "is-glob@npm:2.0.1"
@@ -14301,6 +15623,15 @@ __metadata:
languageName: node
linkType: hard
+"is-relative@npm:^1.0.0":
+ version: 1.0.0
+ resolution: "is-relative@npm:1.0.0"
+ dependencies:
+ is-unc-path: "npm:^1.0.0"
+ checksum: 10/3271a0df109302ef5e14a29dcd5d23d9788e15ade91a40b942b035827ffbb59f7ce9ff82d036ea798541a52913cbf9d2d0b66456340887b51f3542d57b5a4c05
+ languageName: node
+ linkType: hard
+
"is-set@npm:^2.0.1":
version: 2.0.2
resolution: "is-set@npm:2.0.2"
@@ -14406,6 +15737,15 @@ __metadata:
languageName: node
linkType: hard
+"is-unc-path@npm:^1.0.0":
+ version: 1.0.0
+ resolution: "is-unc-path@npm:1.0.0"
+ dependencies:
+ unc-path-regex: "npm:^0.1.2"
+ checksum: 10/e8abfde203f7409f5b03a5f1f8636e3a41e78b983702ef49d9343eb608cdfe691429398e8815157519b987b739bcfbc73ae7cf4c8582b0ab66add5171088eab6
+ languageName: node
+ linkType: hard
+
"is-unicode-supported@npm:^0.1.0":
version: 0.1.0
resolution: "is-unicode-supported@npm:0.1.0"
@@ -14455,7 +15795,7 @@ __metadata:
languageName: node
linkType: hard
-"is-windows@npm:^1.0.2":
+"is-windows@npm:^1.0.1, is-windows@npm:^1.0.2":
version: 1.0.2
resolution: "is-windows@npm:1.0.2"
checksum: 10/438b7e52656fe3b9b293b180defb4e448088e7023a523ec21a91a80b9ff8cdb3377ddb5b6e60f7c7de4fa8b63ab56e121b6705fe081b3cf1b828b0a380009ad7
@@ -15361,6 +16701,15 @@ __metadata:
languageName: node
linkType: hard
+"jsesc@npm:^3.0.2":
+ version: 3.1.0
+ resolution: "jsesc@npm:3.1.0"
+ bin:
+ jsesc: bin/jsesc
+ checksum: 10/20bd37a142eca5d1794f354db8f1c9aeb54d85e1f5c247b371de05d23a9751ecd7bd3a9c4fc5298ea6fa09a100dafb4190fa5c98c6610b75952c3487f3ce7967
+ languageName: node
+ linkType: hard
+
"jsesc@npm:~0.5.0":
version: 0.5.0
resolution: "jsesc@npm:0.5.0"
@@ -15370,6 +16719,15 @@ __metadata:
languageName: node
linkType: hard
+"jsesc@npm:~3.0.2":
+ version: 3.0.2
+ resolution: "jsesc@npm:3.0.2"
+ bin:
+ jsesc: bin/jsesc
+ checksum: 10/8e5a7de6b70a8bd71f9cb0b5a7ade6a73ae6ab55e697c74cc997cede97417a3a65ed86c36f7dd6125fe49766e8386c845023d9e213916ca92c9dfdd56e2babf3
+ languageName: node
+ linkType: hard
+
"json-bigint@npm:^1.0.0":
version: 1.0.0
resolution: "json-bigint@npm:1.0.0"
@@ -15500,7 +16858,7 @@ __metadata:
languageName: node
linkType: hard
-"json5@npm:^2.2.2, json5@npm:^2.2.3":
+"json5@npm:^2.2.1, json5@npm:^2.2.2, json5@npm:^2.2.3":
version: 2.2.3
resolution: "json5@npm:2.2.3"
bin:
@@ -15706,7 +17064,7 @@ __metadata:
languageName: node
linkType: hard
-"kleur@npm:^4.0.3":
+"kleur@npm:^4.0.3, kleur@npm:^4.1.4":
version: 4.1.5
resolution: "kleur@npm:4.1.5"
checksum: 10/44d84cc4eedd4311099402ef6d4acd9b2d16e08e499d6ef3bb92389bd4692d7ef09e35248c26e27f98acac532122acb12a1bfee645994ae3af4f0a37996da7df
@@ -16647,6 +18005,18 @@ __metadata:
languageName: node
linkType: hard
+"metro-babel-transformer@npm:0.80.12":
+ version: 0.80.12
+ resolution: "metro-babel-transformer@npm:0.80.12"
+ dependencies:
+ "@babel/core": "npm:^7.20.0"
+ flow-enums-runtime: "npm:^0.0.6"
+ hermes-parser: "npm:0.23.1"
+ nullthrows: "npm:^1.1.1"
+ checksum: 10/3912367e269df3ac697d67541d56fed86ab6fc40ce1aa107b8f332402c7a84a3d0991e536897d4877bab2b1986dd21ec7fad0c76704a27c1c2edce0bcf9037a9
+ languageName: node
+ linkType: hard
+
"metro-babel-transformer@npm:0.80.6":
version: 0.80.6
resolution: "metro-babel-transformer@npm:0.80.6"
@@ -16658,6 +18028,15 @@ __metadata:
languageName: node
linkType: hard
+"metro-cache-key@npm:0.80.12":
+ version: 0.80.12
+ resolution: "metro-cache-key@npm:0.80.12"
+ dependencies:
+ flow-enums-runtime: "npm:^0.0.6"
+ checksum: 10/7a06601180604361339d19eb833d61b79cc188a4e6ebe73188cc10fbf3a33e711d74c81d1d19a14b6581bd9dfeebe1b253684360682d033ab55909c9995b6a18
+ languageName: node
+ linkType: hard
+
"metro-cache-key@npm:0.80.6":
version: 0.80.6
resolution: "metro-cache-key@npm:0.80.6"
@@ -16665,6 +18044,17 @@ __metadata:
languageName: node
linkType: hard
+"metro-cache@npm:0.80.12":
+ version: 0.80.12
+ resolution: "metro-cache@npm:0.80.12"
+ dependencies:
+ exponential-backoff: "npm:^3.1.1"
+ flow-enums-runtime: "npm:^0.0.6"
+ metro-core: "npm:0.80.12"
+ checksum: 10/914b599ad4f8a2538e6f4788b3da722aa855688affef3002fe374a0a1cb7dd36ad9224d1ef83f7c17610ebb290cea3cb545bfd67100a216b7bbb3f26f8982c93
+ languageName: node
+ linkType: hard
+
"metro-cache@npm:0.80.6":
version: 0.80.6
resolution: "metro-cache@npm:0.80.6"
@@ -16675,6 +18065,22 @@ __metadata:
languageName: node
linkType: hard
+"metro-config@npm:0.80.12, metro-config@npm:^0.80.9":
+ version: 0.80.12
+ resolution: "metro-config@npm:0.80.12"
+ dependencies:
+ connect: "npm:^3.6.5"
+ cosmiconfig: "npm:^5.0.5"
+ flow-enums-runtime: "npm:^0.0.6"
+ jest-validate: "npm:^29.6.3"
+ metro: "npm:0.80.12"
+ metro-cache: "npm:0.80.12"
+ metro-core: "npm:0.80.12"
+ metro-runtime: "npm:0.80.12"
+ checksum: 10/2d11745d32e8992b78159c275dc54b08bf258871f274634f9824540f1ec80a9b1a9d7eb5493b52078a5a68cccd4fd688cd846dd0802aea2f065b5588e98eb146
+ languageName: node
+ linkType: hard
+
"metro-config@npm:0.80.6, metro-config@npm:^0.80.3":
version: 0.80.6
resolution: "metro-config@npm:0.80.6"
@@ -16690,6 +18096,17 @@ __metadata:
languageName: node
linkType: hard
+"metro-core@npm:0.80.12":
+ version: 0.80.12
+ resolution: "metro-core@npm:0.80.12"
+ dependencies:
+ flow-enums-runtime: "npm:^0.0.6"
+ lodash.throttle: "npm:^4.1.1"
+ metro-resolver: "npm:0.80.12"
+ checksum: 10/d29ab20df4d19c1d8c5178f7b182e050c659f022ab2adc669504c7ef7fd5d76cdde02936d1599e6d6137e353cbf4fef6b3cfa6aaf217bca954fc23cbf1b61f18
+ languageName: node
+ linkType: hard
+
"metro-core@npm:0.80.6, metro-core@npm:^0.80.3":
version: 0.80.6
resolution: "metro-core@npm:0.80.6"
@@ -16700,6 +18117,29 @@ __metadata:
languageName: node
linkType: hard
+"metro-file-map@npm:0.80.12":
+ version: 0.80.12
+ resolution: "metro-file-map@npm:0.80.12"
+ dependencies:
+ anymatch: "npm:^3.0.3"
+ debug: "npm:^2.2.0"
+ fb-watchman: "npm:^2.0.0"
+ flow-enums-runtime: "npm:^0.0.6"
+ fsevents: "npm:^2.3.2"
+ graceful-fs: "npm:^4.2.4"
+ invariant: "npm:^2.2.4"
+ jest-worker: "npm:^29.6.3"
+ micromatch: "npm:^4.0.4"
+ node-abort-controller: "npm:^3.1.1"
+ nullthrows: "npm:^1.1.1"
+ walker: "npm:^1.0.7"
+ dependenciesMeta:
+ fsevents:
+ optional: true
+ checksum: 10/a0c06da7c89bfbbe17adadb46470274e2e1ffee43126a08f665db230d7831c6195410ea7165f94182e18a27359e140fc8272d2271c04bf0286a1ea95106a3758
+ languageName: node
+ linkType: hard
+
"metro-file-map@npm:0.80.6":
version: 0.80.6
resolution: "metro-file-map@npm:0.80.6"
@@ -16722,6 +18162,16 @@ __metadata:
languageName: node
linkType: hard
+"metro-minify-terser@npm:0.80.12":
+ version: 0.80.12
+ resolution: "metro-minify-terser@npm:0.80.12"
+ dependencies:
+ flow-enums-runtime: "npm:^0.0.6"
+ terser: "npm:^5.15.0"
+ checksum: 10/ff527b3f04c5814db139e55ceb7689aaaf0af5c7fbb0eb5d4a6f22044932dfb10bd385d388fa7b352acd03a2d078edaf43a6b5cd11cbc87a7c5502a34fc12735
+ languageName: node
+ linkType: hard
+
"metro-minify-terser@npm:0.80.6":
version: 0.80.6
resolution: "metro-minify-terser@npm:0.80.6"
@@ -16731,6 +18181,15 @@ __metadata:
languageName: node
linkType: hard
+"metro-resolver@npm:0.80.12":
+ version: 0.80.12
+ resolution: "metro-resolver@npm:0.80.12"
+ dependencies:
+ flow-enums-runtime: "npm:^0.0.6"
+ checksum: 10/e8609f1b93f1bbe7a9f97dd3fa2a6669c0a51f8360fea9a73e528fc25615f7ef61bd8ad9feb9a52fdbf4405a4065195f053183626f3ab56f54225ebefee574ac
+ languageName: node
+ linkType: hard
+
"metro-resolver@npm:0.80.6":
version: 0.80.6
resolution: "metro-resolver@npm:0.80.6"
@@ -16738,6 +18197,16 @@ __metadata:
languageName: node
linkType: hard
+"metro-runtime@npm:0.80.12":
+ version: 0.80.12
+ resolution: "metro-runtime@npm:0.80.12"
+ dependencies:
+ "@babel/runtime": "npm:^7.25.0"
+ flow-enums-runtime: "npm:^0.0.6"
+ checksum: 10/8a09e7001bd54331c50145d02e6a2b67589da4dd0da3ff1cdb83e6ce161b9079e2a52a4722db8f222b46f666e3dbfe1fc59ee7c277325763a162e3d27ba81d38
+ languageName: node
+ linkType: hard
+
"metro-runtime@npm:0.80.6, metro-runtime@npm:^0.80.3":
version: 0.80.6
resolution: "metro-runtime@npm:0.80.6"
@@ -16747,6 +18216,23 @@ __metadata:
languageName: node
linkType: hard
+"metro-source-map@npm:0.80.12":
+ version: 0.80.12
+ resolution: "metro-source-map@npm:0.80.12"
+ dependencies:
+ "@babel/traverse": "npm:^7.20.0"
+ "@babel/types": "npm:^7.20.0"
+ flow-enums-runtime: "npm:^0.0.6"
+ invariant: "npm:^2.2.4"
+ metro-symbolicate: "npm:0.80.12"
+ nullthrows: "npm:^1.1.1"
+ ob1: "npm:0.80.12"
+ source-map: "npm:^0.5.6"
+ vlq: "npm:^1.0.0"
+ checksum: 10/ad6e0cf7f4d2727ecb45a082b4ab92915df8c574de0a905023a53e501a32f619aaeb0f94645aca048ae322176600867f5f21119349261427a2de27cb27ef0ef1
+ languageName: node
+ linkType: hard
+
"metro-source-map@npm:0.80.6, metro-source-map@npm:^0.80.3":
version: 0.80.6
resolution: "metro-source-map@npm:0.80.6"
@@ -16763,6 +18249,23 @@ __metadata:
languageName: node
linkType: hard
+"metro-symbolicate@npm:0.80.12":
+ version: 0.80.12
+ resolution: "metro-symbolicate@npm:0.80.12"
+ dependencies:
+ flow-enums-runtime: "npm:^0.0.6"
+ invariant: "npm:^2.2.4"
+ metro-source-map: "npm:0.80.12"
+ nullthrows: "npm:^1.1.1"
+ source-map: "npm:^0.5.6"
+ through2: "npm:^2.0.1"
+ vlq: "npm:^1.0.0"
+ bin:
+ metro-symbolicate: src/index.js
+ checksum: 10/0c1dd055691bd670fb73a146f7e2fa3235a5afa3135996e681384676a439e10c9efe398d5b07d588907adbfbf65228829ceb57dab2c19a61eb79dde60bb7dc31
+ languageName: node
+ linkType: hard
+
"metro-symbolicate@npm:0.80.6":
version: 0.80.6
resolution: "metro-symbolicate@npm:0.80.6"
@@ -16779,6 +18282,20 @@ __metadata:
languageName: node
linkType: hard
+"metro-transform-plugins@npm:0.80.12":
+ version: 0.80.12
+ resolution: "metro-transform-plugins@npm:0.80.12"
+ dependencies:
+ "@babel/core": "npm:^7.20.0"
+ "@babel/generator": "npm:^7.20.0"
+ "@babel/template": "npm:^7.0.0"
+ "@babel/traverse": "npm:^7.20.0"
+ flow-enums-runtime: "npm:^0.0.6"
+ nullthrows: "npm:^1.1.1"
+ checksum: 10/801510bde9cb70ba47572c3d5d42f98fc2ee173a48ca39893cbdeb689de54d5a1fea5383ba4fe388f334af06ecb651e5634b5e7611223e217668c98f8666c913
+ languageName: node
+ linkType: hard
+
"metro-transform-plugins@npm:0.80.6":
version: 0.80.6
resolution: "metro-transform-plugins@npm:0.80.6"
@@ -16792,6 +18309,27 @@ __metadata:
languageName: node
linkType: hard
+"metro-transform-worker@npm:0.80.12":
+ version: 0.80.12
+ resolution: "metro-transform-worker@npm:0.80.12"
+ dependencies:
+ "@babel/core": "npm:^7.20.0"
+ "@babel/generator": "npm:^7.20.0"
+ "@babel/parser": "npm:^7.20.0"
+ "@babel/types": "npm:^7.20.0"
+ flow-enums-runtime: "npm:^0.0.6"
+ metro: "npm:0.80.12"
+ metro-babel-transformer: "npm:0.80.12"
+ metro-cache: "npm:0.80.12"
+ metro-cache-key: "npm:0.80.12"
+ metro-minify-terser: "npm:0.80.12"
+ metro-source-map: "npm:0.80.12"
+ metro-transform-plugins: "npm:0.80.12"
+ nullthrows: "npm:^1.1.1"
+ checksum: 10/a0802ebbc308a3bd6c81f9a1c640c62a8918f4d4e73da2184d24be10014ce6bc1cef53c0ef6a59568ecc0d0d44d43e38ec595d4abda043f93072613261074371
+ languageName: node
+ linkType: hard
+
"metro-transform-worker@npm:0.80.6":
version: 0.80.6
resolution: "metro-transform-worker@npm:0.80.6"
@@ -16812,6 +18350,58 @@ __metadata:
languageName: node
linkType: hard
+"metro@npm:0.80.12":
+ version: 0.80.12
+ resolution: "metro@npm:0.80.12"
+ dependencies:
+ "@babel/code-frame": "npm:^7.0.0"
+ "@babel/core": "npm:^7.20.0"
+ "@babel/generator": "npm:^7.20.0"
+ "@babel/parser": "npm:^7.20.0"
+ "@babel/template": "npm:^7.0.0"
+ "@babel/traverse": "npm:^7.20.0"
+ "@babel/types": "npm:^7.20.0"
+ accepts: "npm:^1.3.7"
+ chalk: "npm:^4.0.0"
+ ci-info: "npm:^2.0.0"
+ connect: "npm:^3.6.5"
+ debug: "npm:^2.2.0"
+ denodeify: "npm:^1.2.1"
+ error-stack-parser: "npm:^2.0.6"
+ flow-enums-runtime: "npm:^0.0.6"
+ graceful-fs: "npm:^4.2.4"
+ hermes-parser: "npm:0.23.1"
+ image-size: "npm:^1.0.2"
+ invariant: "npm:^2.2.4"
+ jest-worker: "npm:^29.6.3"
+ jsc-safe-url: "npm:^0.2.2"
+ lodash.throttle: "npm:^4.1.1"
+ metro-babel-transformer: "npm:0.80.12"
+ metro-cache: "npm:0.80.12"
+ metro-cache-key: "npm:0.80.12"
+ metro-config: "npm:0.80.12"
+ metro-core: "npm:0.80.12"
+ metro-file-map: "npm:0.80.12"
+ metro-resolver: "npm:0.80.12"
+ metro-runtime: "npm:0.80.12"
+ metro-source-map: "npm:0.80.12"
+ metro-symbolicate: "npm:0.80.12"
+ metro-transform-plugins: "npm:0.80.12"
+ metro-transform-worker: "npm:0.80.12"
+ mime-types: "npm:^2.1.27"
+ nullthrows: "npm:^1.1.1"
+ serialize-error: "npm:^2.1.0"
+ source-map: "npm:^0.5.6"
+ strip-ansi: "npm:^6.0.0"
+ throat: "npm:^5.0.0"
+ ws: "npm:^7.5.10"
+ yargs: "npm:^17.6.2"
+ bin:
+ metro: src/cli.js
+ checksum: 10/b44280b16d3671be97d11327a9fe0bb2db014a6dcedaab9e88d58696a8133246ef7f8290e9fac0841534872132bbc0d7132745b02f3584339c0999d9e7a58c10
+ languageName: node
+ linkType: hard
+
"metro@npm:0.80.6, metro@npm:^0.80.3":
version: 0.80.6
resolution: "metro@npm:0.80.6"
@@ -17950,6 +19540,13 @@ __metadata:
languageName: node
linkType: hard
+"node-releases@npm:^2.0.19":
+ version: 2.0.19
+ resolution: "node-releases@npm:2.0.19"
+ checksum: 10/c2b33b4f0c40445aee56141f13ca692fa6805db88510e5bbb3baadb2da13e1293b738e638e15e4a8eb668bb9e97debb08e7a35409b477b5cc18f171d35a83045
+ languageName: node
+ linkType: hard
+
"node-stream-zip@npm:^1.9.1":
version: 1.15.0
resolution: "node-stream-zip@npm:1.15.0"
@@ -18171,7 +19768,7 @@ __metadata:
languageName: node
linkType: hard
-"npm-run-path@npm:^4.0.1":
+"npm-run-path@npm:^4.0.0, npm-run-path@npm:^4.0.1":
version: 4.0.1
resolution: "npm-run-path@npm:4.0.1"
dependencies:
@@ -18361,6 +19958,15 @@ __metadata:
languageName: node
linkType: hard
+"ob1@npm:0.80.12":
+ version: 0.80.12
+ resolution: "ob1@npm:0.80.12"
+ dependencies:
+ flow-enums-runtime: "npm:^0.0.6"
+ checksum: 10/c78af51d6ecf47ba5198bc7eb27d0456a287589533f1445e6d595e2d067f6f8038da02a98e5faa4a6c3d0c04f77c570bc9b29c652fec55518884c40c73212f17
+ languageName: node
+ linkType: hard
+
"ob1@npm:0.80.6":
version: 0.80.6
resolution: "ob1@npm:0.80.6"
@@ -19270,6 +20876,13 @@ __metadata:
languageName: node
linkType: hard
+"picocolors@npm:^1.1.1":
+ version: 1.1.1
+ resolution: "picocolors@npm:1.1.1"
+ checksum: 10/e1cf46bf84886c79055fdfa9dcb3e4711ad259949e3565154b004b260cd356c5d54b31a1437ce9782624bf766272fe6b0154f5f0c744fb7af5d454d2b60db045
+ languageName: node
+ linkType: hard
+
"picomatch@npm:^2.0.4, picomatch@npm:^2.2.1, picomatch@npm:^2.2.3, picomatch@npm:^2.3.1":
version: 2.3.1
resolution: "picomatch@npm:2.3.1"
@@ -19346,6 +20959,15 @@ __metadata:
languageName: node
linkType: hard
+"pkg-up@npm:^3.1.0":
+ version: 3.1.0
+ resolution: "pkg-up@npm:3.1.0"
+ dependencies:
+ find-up: "npm:^3.0.0"
+ checksum: 10/5bac346b7c7c903613c057ae3ab722f320716199d753f4a7d053d38f2b5955460f3e6ab73b4762c62fd3e947f58e04f1343e92089e7bb6091c90877406fcd8c8
+ languageName: node
+ linkType: hard
+
"plist@npm:^3.0.5, plist@npm:^3.1.0":
version: 3.1.0
resolution: "plist@npm:3.1.0"
@@ -20003,6 +21625,38 @@ __metadata:
languageName: node
linkType: hard
+"react-native-builder-bob@npm:^0.35.2":
+ version: 0.35.2
+ resolution: "react-native-builder-bob@npm:0.35.2"
+ dependencies:
+ "@babel/core": "npm:^7.25.2"
+ "@babel/plugin-transform-strict-mode": "npm:^7.24.7"
+ "@babel/preset-env": "npm:^7.25.2"
+ "@babel/preset-flow": "npm:^7.24.7"
+ "@babel/preset-react": "npm:^7.24.7"
+ "@babel/preset-typescript": "npm:^7.24.7"
+ babel-plugin-module-resolver: "npm:^5.0.2"
+ browserslist: "npm:^4.20.4"
+ cosmiconfig: "npm:^9.0.0"
+ cross-spawn: "npm:^7.0.3"
+ dedent: "npm:^0.7.0"
+ del: "npm:^6.1.1"
+ escape-string-regexp: "npm:^4.0.0"
+ fs-extra: "npm:^10.1.0"
+ glob: "npm:^8.0.3"
+ is-git-dirty: "npm:^2.0.1"
+ json5: "npm:^2.2.1"
+ kleur: "npm:^4.1.4"
+ metro-config: "npm:^0.80.9"
+ prompts: "npm:^2.4.2"
+ which: "npm:^2.0.2"
+ yargs: "npm:^17.5.1"
+ bin:
+ bob: bin/bob
+ checksum: 10/cffafaa3cc21dc716711dd282f1c163c82d5fded75c9a02034b34f54bb678cf0f255514bb773ad0fff39d939c5431f49aa663a4b14febd678d1f596e7774c337
+ languageName: node
+ linkType: hard
+
"react-native-device-info@npm:^13.0.0":
version: 13.0.0
resolution: "react-native-device-info@npm:13.0.0"
@@ -20036,6 +21690,7 @@ __metadata:
"@react-native-firebase/perf": "npm:21.6.2"
"@react-native-firebase/remote-config": "npm:21.6.2"
"@react-native-firebase/storage": "npm:21.6.2"
+ "@react-native-firebase/vertexai": "npm:0.0.1"
"@react-native/babel-preset": "npm:^0.74.87"
"@react-native/metro-config": "npm:^0.74.87"
axios: "npm:^1.7.7"
@@ -20516,6 +22171,15 @@ __metadata:
languageName: node
linkType: hard
+"regenerate-unicode-properties@npm:^10.2.0":
+ version: 10.2.0
+ resolution: "regenerate-unicode-properties@npm:10.2.0"
+ dependencies:
+ regenerate: "npm:^1.4.2"
+ checksum: 10/9150eae6fe04a8c4f2ff06077396a86a98e224c8afad8344b1b656448e89e84edcd527e4b03aa5476774129eb6ad328ed684f9c1459794a935ec0cc17ce14329
+ languageName: node
+ linkType: hard
+
"regenerate@npm:^1.4.2":
version: 1.4.2
resolution: "regenerate@npm:1.4.2"
@@ -20572,6 +22236,20 @@ __metadata:
languageName: node
linkType: hard
+"regexpu-core@npm:^6.2.0":
+ version: 6.2.0
+ resolution: "regexpu-core@npm:6.2.0"
+ dependencies:
+ regenerate: "npm:^1.4.2"
+ regenerate-unicode-properties: "npm:^10.2.0"
+ regjsgen: "npm:^0.8.0"
+ regjsparser: "npm:^0.12.0"
+ unicode-match-property-ecmascript: "npm:^2.0.0"
+ unicode-match-property-value-ecmascript: "npm:^2.1.0"
+ checksum: 10/4d054ffcd98ca4f6ca7bf0df6598ed5e4a124264602553308add41d4fa714a0c5bcfb5bc868ac91f7060a9c09889cc21d3180a3a14c5f9c5838442806129ced3
+ languageName: node
+ linkType: hard
+
"registry-auth-token@npm:^5.0.1":
version: 5.0.2
resolution: "registry-auth-token@npm:5.0.2"
@@ -20590,6 +22268,24 @@ __metadata:
languageName: node
linkType: hard
+"regjsgen@npm:^0.8.0":
+ version: 0.8.0
+ resolution: "regjsgen@npm:0.8.0"
+ checksum: 10/b930f03347e4123c917d7b40436b4f87f625b8dd3e705b447ddd44804e4616c3addb7453f0902d6e914ab0446c30e816e445089bb641a4714237fe8141a0ef9d
+ languageName: node
+ linkType: hard
+
+"regjsparser@npm:^0.12.0":
+ version: 0.12.0
+ resolution: "regjsparser@npm:0.12.0"
+ dependencies:
+ jsesc: "npm:~3.0.2"
+ bin:
+ regjsparser: bin/parser
+ checksum: 10/c2d6506b3308679de5223a8916984198e0493649a67b477c66bdb875357e3785abbf3bedf7c5c2cf8967d3b3a7bdf08b7cbd39e65a70f9e1ffad584aecf5f06a
+ languageName: node
+ linkType: hard
+
"regjsparser@npm:^0.9.1":
version: 0.9.1
resolution: "regjsparser@npm:0.9.1"
@@ -20721,6 +22417,13 @@ __metadata:
languageName: node
linkType: hard
+"reselect@npm:^4.1.7":
+ version: 4.1.8
+ resolution: "reselect@npm:4.1.8"
+ checksum: 10/199984d9872f71cd207f4aa6e6fd2bd48d95154f7aa9b3aee3398335f39f5491059e732f28c12e9031d5d434adab2c458dc8af5afb6564d0ad37e1644445e09c
+ languageName: node
+ linkType: hard
+
"resolve-cwd@npm:^3.0.0":
version: 3.0.0
resolution: "resolve-cwd@npm:3.0.0"
@@ -23249,6 +24952,13 @@ __metadata:
languageName: node
linkType: hard
+"unc-path-regex@npm:^0.1.2":
+ version: 0.1.2
+ resolution: "unc-path-regex@npm:0.1.2"
+ checksum: 10/a05fa2006bf4606051c10fc7968f08ce7b28fa646befafa282813aeb1ac1a56f65cb1b577ca7851af2726198d59475bb49b11776036257b843eaacee2860a4ec
+ languageName: node
+ linkType: hard
+
"undici-types@npm:~5.26.4":
version: 5.26.5
resolution: "undici-types@npm:5.26.5"
@@ -23579,6 +25289,20 @@ __metadata:
languageName: node
linkType: hard
+"update-browserslist-db@npm:^1.1.1":
+ version: 1.1.2
+ resolution: "update-browserslist-db@npm:1.1.2"
+ dependencies:
+ escalade: "npm:^3.2.0"
+ picocolors: "npm:^1.1.1"
+ peerDependencies:
+ browserslist: ">= 4.21.0"
+ bin:
+ update-browserslist-db: cli.js
+ checksum: 10/e7bf8221dfb21eba4a770cd803df94625bb04f65a706aa94c567de9600fe4eb6133fda016ec471dad43b9e7959c1bffb6580b5e20a87808d2e8a13e3892699a9
+ languageName: node
+ linkType: hard
+
"update-notifier-cjs@npm:^5.1.6":
version: 5.1.6
resolution: "update-notifier-cjs@npm:5.1.6"
@@ -24048,7 +25772,7 @@ __metadata:
languageName: node
linkType: hard
-"which@npm:^2.0.1":
+"which@npm:^2.0.1, which@npm:^2.0.2":
version: 2.0.2
resolution: "which@npm:2.0.2"
dependencies:
@@ -24504,7 +26228,7 @@ __metadata:
languageName: node
linkType: hard
-"yargs@npm:17.7.2, yargs@npm:^17.0.0, yargs@npm:^17.3.1, yargs@npm:^17.6.2, yargs@npm:^17.7.2":
+"yargs@npm:17.7.2, yargs@npm:^17.0.0, yargs@npm:^17.3.1, yargs@npm:^17.5.1, yargs@npm:^17.6.2, yargs@npm:^17.7.2":
version: 17.7.2
resolution: "yargs@npm:17.7.2"
dependencies:
From 3bfdcdbb02675dd1876886eeeb6bc4ef187713e5 Mon Sep 17 00:00:00 2001
From: russellwheatley
Date: Wed, 8 Jan 2025 16:22:30 +0000
Subject: [PATCH 007/115] package.json updates
---
packages/vertexai/package.json | 3 ++-
tests/package.json | 1 +
yarn.lock | 21 +++++++++++++++++++++
3 files changed, 24 insertions(+), 1 deletion(-)
diff --git a/packages/vertexai/package.json b/packages/vertexai/package.json
index 5ef0749728..8c0df7b430 100644
--- a/packages/vertexai/package.json
+++ b/packages/vertexai/package.json
@@ -30,7 +30,8 @@
"access": "public"
},
"devDependencies": {
- "react-native-builder-bob": "^0.35.2"
+ "react-native-builder-bob": "^0.35.2",
+ "typescript": "^5.7.2"
},
"source": "./lib/index.ts",
"module": "./dist/module/index.js",
diff --git a/tests/package.json b/tests/package.json
index 0b2819c594..9a2ee5fd19 100644
--- a/tests/package.json
+++ b/tests/package.json
@@ -27,6 +27,7 @@
"@react-native-firebase/perf": "21.6.2",
"@react-native-firebase/remote-config": "21.6.2",
"@react-native-firebase/storage": "21.6.2",
+ "@react-native-firebase/vertexai": "0.0.1",
"postinstall-postinstall": "2.1.0",
"react": "18.3.1",
"react-native": "0.74.5",
diff --git a/yarn.lock b/yarn.lock
index 675c0562bf..ddf7305504 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -7574,6 +7574,7 @@ __metadata:
resolution: "@react-native-firebase/vertexai@workspace:packages/vertexai"
dependencies:
react-native-builder-bob: "npm:^0.35.2"
+ typescript: "npm:^5.7.2"
peerDependencies:
"@react-native-firebase/app": 21.6.2
languageName: unknown
@@ -24890,6 +24891,16 @@ __metadata:
languageName: node
linkType: hard
+"typescript@npm:^5.7.2":
+ version: 5.7.2
+ resolution: "typescript@npm:5.7.2"
+ bin:
+ tsc: bin/tsc
+ tsserver: bin/tsserver
+ checksum: 10/4caa3904df69db9d4a8bedc31bafc1e19ffb7b24fbde2997a1633ae1398d0de5bdbf8daf602ccf3b23faddf1aeeb9b795223a2ed9c9a4fdcaf07bfde114a401a
+ languageName: node
+ linkType: hard
+
"typescript@patch:typescript@npm%3A>=3 < 6#optional!builtin":
version: 5.3.3
resolution: "typescript@patch:typescript@npm%3A5.3.3#optional!builtin::version=5.3.3&hash=e012d7"
@@ -24910,6 +24921,16 @@ __metadata:
languageName: node
linkType: hard
+"typescript@patch:typescript@npm%3A^5.7.2#optional!builtin":
+ version: 5.7.2
+ resolution: "typescript@patch:typescript@npm%3A5.7.2#optional!builtin::version=5.7.2&hash=cef18b"
+ bin:
+ tsc: bin/tsc
+ tsserver: bin/tsserver
+ checksum: 10/ff27fc124bceb8969be722baa38af945b2505767cf794de3e2715e58f61b43780284060287d651fcbbdfb6f917f4653b20f4751991f17e0706db389b9bb3f75d
+ languageName: node
+ linkType: hard
+
"typical@npm:^2.6.1":
version: 2.6.1
resolution: "typical@npm:2.6.1"
From 91e2091c1c712f694a4ac2953e46a01b65bdbde2 Mon Sep 17 00:00:00 2001
From: russellwheatley
Date: Thu, 9 Jan 2025 11:10:53 +0000
Subject: [PATCH 008/115] fix: format & fix TS type warnings
---
packages/vertexai/lib/methods/chat-session.ts | 13 ++--
.../vertexai/lib/requests/request-helpers.ts | 2 +
packages/vertexai/lib/requests/request.ts | 49 ++++++---------
.../vertexai/lib/requests/response-helpers.ts | 62 ++++++++-----------
.../vertexai/lib/requests/schema-builder.ts | 45 ++++++--------
5 files changed, 71 insertions(+), 100 deletions(-)
diff --git a/packages/vertexai/lib/methods/chat-session.ts b/packages/vertexai/lib/methods/chat-session.ts
index d22393d5b7..75b15948b9 100644
--- a/packages/vertexai/lib/methods/chat-session.ts
+++ b/packages/vertexai/lib/methods/chat-session.ts
@@ -23,6 +23,7 @@ import {
Part,
RequestOptions,
StartChatParams,
+ EnhancedGenerateContentResponse,
} from '../types';
import { formatNewContent } from '../requests/request-helpers';
import { formatBlockErrorMessage } from '../requests/response-helpers';
@@ -91,13 +92,13 @@ export class ChatSession {
.then(() =>
generateContent(this._apiSettings, this.model, generateContentRequest, this.requestOptions),
)
- .then(result => {
+ .then((result: GenerateContentResult) => {
if (result.response.candidates && result.response.candidates.length > 0) {
this._history.push(newContent);
const responseContent: Content = {
- parts: result.response.candidates?.[0].content.parts || [],
+ parts: result.response.candidates?.[0]?.content.parts || [],
// Response seems to come back without a role set.
- role: result.response.candidates?.[0].content.role || 'model',
+ role: result.response.candidates?.[0]?.content.role || 'model',
};
this._history.push(responseContent);
} else {
@@ -149,15 +150,15 @@ export class ChatSession {
throw new Error(SILENT_ERROR);
})
.then(streamResult => streamResult.response)
- .then(response => {
+ .then((response: EnhancedGenerateContentResponse) => {
if (response.candidates && response.candidates.length > 0) {
this._history.push(newContent);
- const responseContent = { ...response.candidates[0].content };
+ const responseContent = { ...response.candidates[0]?.content };
// Response seems to come back without a role set.
if (!responseContent.role) {
responseContent.role = 'model';
}
- this._history.push(responseContent);
+ this._history.push(responseContent as Content);
} else {
const blockErrorMessage = formatBlockErrorMessage(response);
if (blockErrorMessage) {
diff --git a/packages/vertexai/lib/requests/request-helpers.ts b/packages/vertexai/lib/requests/request-helpers.ts
index 44405cb6f4..77809f1edd 100644
--- a/packages/vertexai/lib/requests/request-helpers.ts
+++ b/packages/vertexai/lib/requests/request-helpers.ts
@@ -33,6 +33,8 @@ export function formatSystemInstruction(input?: string | Part | Content): Conten
return input as Content;
}
}
+
+ return undefined;
}
export function formatNewContent(request: string | Array): Content {
diff --git a/packages/vertexai/lib/requests/request.ts b/packages/vertexai/lib/requests/request.ts
index f81b40635e..058dcb8a3c 100644
--- a/packages/vertexai/lib/requests/request.ts
+++ b/packages/vertexai/lib/requests/request.ts
@@ -23,14 +23,14 @@ import {
DEFAULT_BASE_URL,
DEFAULT_FETCH_TIMEOUT_MS,
LANGUAGE_TAG,
- PACKAGE_VERSION
+ PACKAGE_VERSION,
} from '../constants';
import { logger } from '../logger';
export enum Task {
GENERATE_CONTENT = 'generateContent',
STREAM_GENERATE_CONTENT = 'streamGenerateContent',
- COUNT_TOKENS = 'countTokens'
+ COUNT_TOKENS = 'countTokens',
}
export class RequestUrl {
@@ -39,7 +39,7 @@ export class RequestUrl {
public task: Task,
public apiSettings: ApiSettings,
public stream: boolean,
- public requestOptions?: RequestOptions
+ public requestOptions?: RequestOptions,
) {}
toString(): string {
// TODO: allow user-set option if that feature becomes available
@@ -88,9 +88,7 @@ export async function getHeaders(url: RequestUrl): Promise {
if (appCheckToken) {
headers.append('X-Firebase-AppCheck', appCheckToken.token);
if (appCheckToken.error) {
- logger.warn(
- `Unable to obtain a valid App Check token: ${appCheckToken.error.message}`
- );
+ logger.warn(`Unable to obtain a valid App Check token: ${appCheckToken.error.message}`);
}
}
}
@@ -111,7 +109,7 @@ export async function constructRequest(
apiSettings: ApiSettings,
stream: boolean,
body: string,
- requestOptions?: RequestOptions
+ requestOptions?: RequestOptions,
): Promise<{ url: string; fetchOptions: RequestInit }> {
const url = new RequestUrl(model, task, apiSettings, stream, requestOptions);
return {
@@ -119,8 +117,8 @@ export async function constructRequest(
fetchOptions: {
method: 'POST',
headers: await getHeaders(url),
- body
- }
+ body,
+ },
};
}
@@ -130,20 +128,13 @@ export async function makeRequest(
apiSettings: ApiSettings,
stream: boolean,
body: string,
- requestOptions?: RequestOptions
+ requestOptions?: RequestOptions,
): Promise {
const url = new RequestUrl(model, task, apiSettings, stream, requestOptions);
let response;
let fetchTimeoutId: string | number | NodeJS.Timeout | undefined;
try {
- const request = await constructRequest(
- model,
- task,
- apiSettings,
- stream,
- body,
- requestOptions
- );
+ const request = await constructRequest(model, task, apiSettings, stream, body, requestOptions);
// Timeout is 180s by default
const timeoutMillis =
requestOptions?.timeout != null && requestOptions.timeout >= 0
@@ -169,15 +160,11 @@ export async function makeRequest(
}
if (
response.status === 403 &&
- errorDetails.some(
- (detail: ErrorDetails) => detail.reason === 'SERVICE_DISABLED'
- ) &&
+ errorDetails.some((detail: ErrorDetails) => detail.reason === 'SERVICE_DISABLED') &&
errorDetails.some((detail: ErrorDetails) =>
- (
- detail.links as Array>
- )?.[0]?.description.includes(
- 'Google developers console API activation'
- )
+ (detail.links as Array>)?.[0]?.description?.includes(
+ 'Google developers console API activation',
+ ),
)
) {
throw new VertexAIError(
@@ -192,8 +179,8 @@ export async function makeRequest(
{
status: response.status,
statusText: response.statusText,
- errorDetails
- }
+ errorDetails,
+ },
);
}
throw new VertexAIError(
@@ -202,8 +189,8 @@ export async function makeRequest(
{
status: response.status,
statusText: response.statusText,
- errorDetails
- }
+ errorDetails,
+ },
);
}
} catch (e) {
@@ -215,7 +202,7 @@ export async function makeRequest(
) {
err = new VertexAIError(
VertexAIErrorCode.ERROR,
- `Error fetching from ${url.toString()}: ${e.message}`
+ `Error fetching from ${url.toString()}: ${e.message}`,
);
err.stack = e.stack;
}
diff --git a/packages/vertexai/lib/requests/response-helpers.ts b/packages/vertexai/lib/requests/response-helpers.ts
index 27347d10f0..c7abc9d923 100644
--- a/packages/vertexai/lib/requests/response-helpers.ts
+++ b/packages/vertexai/lib/requests/response-helpers.ts
@@ -21,7 +21,7 @@ import {
FunctionCall,
GenerateContentCandidate,
GenerateContentResponse,
- VertexAIErrorCode
+ VertexAIErrorCode,
} from '../types';
import { VertexAIError } from '../errors';
import { logger } from '../logger';
@@ -31,7 +31,7 @@ import { logger } from '../logger';
* other modifications that improve usability.
*/
export function createEnhancedContentResponse(
- response: GenerateContentResponse
+ response: GenerateContentResponse,
): EnhancedGenerateContentResponse {
/**
* The Vertex AI backend omits default values.
@@ -39,8 +39,8 @@ export function createEnhancedContentResponse(
* response, since it has index 0, and 0 is a default value.
* See: https://github.com/firebase/firebase-js-sdk/issues/8566
*/
- if (response.candidates && !response.candidates[0].hasOwnProperty('index')) {
- response.candidates[0].index = 0;
+ if (response.candidates && !response.candidates[0]?.hasOwnProperty('index')) {
+ response.candidates[0]!.index = 0;
}
const responseWithHelpers = addHelpers(response);
@@ -51,27 +51,25 @@ export function createEnhancedContentResponse(
* Adds convenience helper methods to a response object, including stream
* chunks (as long as each chunk is a complete GenerateContentResponse JSON).
*/
-export function addHelpers(
- response: GenerateContentResponse
-): EnhancedGenerateContentResponse {
+export function addHelpers(response: GenerateContentResponse): EnhancedGenerateContentResponse {
(response as EnhancedGenerateContentResponse).text = () => {
if (response.candidates && response.candidates.length > 0) {
if (response.candidates.length > 1) {
logger.warn(
`This response had ${response.candidates.length} ` +
`candidates. Returning text from the first candidate only. ` +
- `Access response.candidates directly to use the other candidates.`
+ `Access response.candidates directly to use the other candidates.`,
);
}
- if (hadBadFinishReason(response.candidates[0])) {
+ if (hadBadFinishReason(response.candidates[0]!)) {
throw new VertexAIError(
VertexAIErrorCode.RESPONSE_ERROR,
`Response error: ${formatBlockErrorMessage(
- response
+ response,
)}. Response body stored in error.response`,
{
- response
- }
+ response,
+ },
);
}
return getText(response);
@@ -80,8 +78,8 @@ export function addHelpers(
VertexAIErrorCode.RESPONSE_ERROR,
`Text not available. ${formatBlockErrorMessage(response)}`,
{
- response
- }
+ response,
+ },
);
}
return '';
@@ -92,18 +90,18 @@ export function addHelpers(
logger.warn(
`This response had ${response.candidates.length} ` +
`candidates. Returning function calls from the first candidate only. ` +
- `Access response.candidates directly to use the other candidates.`
+ `Access response.candidates directly to use the other candidates.`,
);
}
- if (hadBadFinishReason(response.candidates[0])) {
+ if (hadBadFinishReason(response.candidates[0]!)) {
throw new VertexAIError(
VertexAIErrorCode.RESPONSE_ERROR,
`Response error: ${formatBlockErrorMessage(
- response
+ response,
)}. Response body stored in error.response`,
{
- response
- }
+ response,
+ },
);
}
return getFunctionCalls(response);
@@ -112,8 +110,8 @@ export function addHelpers(
VertexAIErrorCode.RESPONSE_ERROR,
`Function call not available. ${formatBlockErrorMessage(response)}`,
{
- response
- }
+ response,
+ },
);
}
return undefined;
@@ -126,7 +124,7 @@ export function addHelpers(
*/
export function getText(response: GenerateContentResponse): string {
const textStrings = [];
- if (response.candidates?.[0].content?.parts) {
+ if (response.candidates?.[0]?.content?.parts) {
for (const part of response.candidates?.[0].content?.parts) {
if (part.text) {
textStrings.push(part.text);
@@ -143,11 +141,9 @@ export function getText(response: GenerateContentResponse): string {
/**
* Returns {@link FunctionCall}
s associated with first candidate.
*/
-export function getFunctionCalls(
- response: GenerateContentResponse
-): FunctionCall[] | undefined {
+export function getFunctionCalls(response: GenerateContentResponse): FunctionCall[] | undefined {
const functionCalls: FunctionCall[] = [];
- if (response.candidates?.[0].content?.parts) {
+ if (response.candidates?.[0]?.content?.parts) {
for (const part of response.candidates?.[0].content?.parts) {
if (part.functionCall) {
functionCalls.push(part.functionCall);
@@ -164,20 +160,12 @@ export function getFunctionCalls(
const badFinishReasons = [FinishReason.RECITATION, FinishReason.SAFETY];
function hadBadFinishReason(candidate: GenerateContentCandidate): boolean {
- return (
- !!candidate.finishReason &&
- badFinishReasons.includes(candidate.finishReason)
- );
+ return !!candidate.finishReason && badFinishReasons.includes(candidate.finishReason);
}
-export function formatBlockErrorMessage(
- response: GenerateContentResponse
-): string {
+export function formatBlockErrorMessage(response: GenerateContentResponse): string {
let message = '';
- if (
- (!response.candidates || response.candidates.length === 0) &&
- response.promptFeedback
- ) {
+ if ((!response.candidates || response.candidates.length === 0) && response.promptFeedback) {
message += 'Response was blocked';
if (response.promptFeedback?.blockReason) {
message += ` due to ${response.promptFeedback.blockReason}`;
diff --git a/packages/vertexai/lib/requests/schema-builder.ts b/packages/vertexai/lib/requests/schema-builder.ts
index 3d219d58b1..c7ce1aff66 100644
--- a/packages/vertexai/lib/requests/schema-builder.ts
+++ b/packages/vertexai/lib/requests/schema-builder.ts
@@ -22,7 +22,7 @@ import {
SchemaType,
SchemaParams,
SchemaRequest,
- ObjectSchemaInterface
+ ObjectSchemaInterface,
} from '../types/schema';
/**
@@ -66,9 +66,7 @@ export abstract class Schema implements SchemaInterface {
}
// Ensure these are explicitly set to avoid TS errors.
this.type = schemaParams.type;
- this.nullable = schemaParams.hasOwnProperty('nullable')
- ? !!schemaParams.nullable
- : false;
+ this.nullable = schemaParams.hasOwnProperty('nullable') ? !!schemaParams.nullable : false;
}
/**
@@ -78,7 +76,7 @@ export abstract class Schema implements SchemaInterface {
*/
toJSON(): SchemaRequest {
const obj: { type: SchemaType; [key: string]: unknown } = {
- type: this.type
+ type: this.type,
};
for (const prop in this) {
if (this.hasOwnProperty(prop) && this[prop] !== undefined) {
@@ -100,13 +98,9 @@ export abstract class Schema implements SchemaInterface {
[k: string]: Schema;
};
optionalProperties?: string[];
- }
+ },
): ObjectSchema {
- return new ObjectSchema(
- objectParams,
- objectParams.properties,
- objectParams.optionalProperties
- );
+ return new ObjectSchema(objectParams, objectParams.properties, objectParams.optionalProperties);
}
// eslint-disable-next-line id-blacklist
@@ -114,9 +108,7 @@ export abstract class Schema implements SchemaInterface {
return new StringSchema(stringParams);
}
- static enumString(
- stringParams: SchemaParams & { enum: string[] }
- ): StringSchema {
+ static enumString(stringParams: SchemaParams & { enum: string[] }): StringSchema {
return new StringSchema(stringParams, stringParams.enum);
}
@@ -155,7 +147,7 @@ export class IntegerSchema extends Schema {
constructor(schemaParams?: SchemaParams) {
super({
type: SchemaType.INTEGER,
- ...schemaParams
+ ...schemaParams,
});
}
}
@@ -168,7 +160,7 @@ export class NumberSchema extends Schema {
constructor(schemaParams?: SchemaParams) {
super({
type: SchemaType.NUMBER,
- ...schemaParams
+ ...schemaParams,
});
}
}
@@ -181,7 +173,7 @@ export class BooleanSchema extends Schema {
constructor(schemaParams?: SchemaParams) {
super({
type: SchemaType.BOOLEAN,
- ...schemaParams
+ ...schemaParams,
});
}
}
@@ -196,7 +188,7 @@ export class StringSchema extends Schema {
constructor(schemaParams?: SchemaParams, enumValues?: string[]) {
super({
type: SchemaType.STRING,
- ...schemaParams
+ ...schemaParams,
});
this.enum = enumValues;
}
@@ -220,10 +212,13 @@ export class StringSchema extends Schema {
* @public
*/
export class ArraySchema extends Schema {
- constructor(schemaParams: SchemaParams, public items: TypedSchema) {
+ constructor(
+ schemaParams: SchemaParams,
+ public items: TypedSchema,
+ ) {
super({
type: SchemaType.ARRAY,
- ...schemaParams
+ ...schemaParams,
});
}
@@ -248,11 +243,11 @@ export class ObjectSchema extends Schema {
public properties: {
[k: string]: TypedSchema;
},
- public optionalProperties: string[] = []
+ public optionalProperties: string[] = [],
) {
super({
type: SchemaType.OBJECT,
- ...schemaParams
+ ...schemaParams,
});
}
@@ -268,16 +263,14 @@ export class ObjectSchema extends Schema {
if (!this.properties.hasOwnProperty(propertyKey)) {
throw new VertexAIError(
VertexAIErrorCode.INVALID_SCHEMA,
- `Property "${propertyKey}" specified in "optionalProperties" does not exist.`
+ `Property "${propertyKey}" specified in "optionalProperties" does not exist.`,
);
}
}
}
for (const propertyKey in this.properties) {
if (this.properties.hasOwnProperty(propertyKey)) {
- obj.properties[propertyKey] = this.properties[
- propertyKey
- ].toJSON() as SchemaRequest;
+ obj.properties[propertyKey] = this.properties[propertyKey]!.toJSON() as SchemaRequest;
if (!this.optionalProperties.includes(propertyKey)) {
required.push(propertyKey);
}
From af1db1fa03c6447f818f7fc3c447e58aa07ef97b Mon Sep 17 00:00:00 2001
From: russellwheatley
Date: Thu, 9 Jan 2025 11:11:48 +0000
Subject: [PATCH 009/115] chore: format stream-reader file
---
.../vertexai/lib/requests/stream-reader.ts | 57 +++++++------------
1 file changed, 20 insertions(+), 37 deletions(-)
diff --git a/packages/vertexai/lib/requests/stream-reader.ts b/packages/vertexai/lib/requests/stream-reader.ts
index 8162407d90..cdd000d0c6 100644
--- a/packages/vertexai/lib/requests/stream-reader.ts
+++ b/packages/vertexai/lib/requests/stream-reader.ts
@@ -21,7 +21,7 @@ import {
GenerateContentResponse,
GenerateContentStreamResult,
Part,
- VertexAIErrorCode
+ VertexAIErrorCode,
} from '../types';
import { VertexAIError } from '../errors';
import { createEnhancedContentResponse } from './response-helpers';
@@ -37,29 +37,24 @@ const responseLineRE = /^data\: (.*)(?:\n\n|\r\r|\r\n\r\n)/;
* @param response - Response from a fetch call
*/
export function processStream(response: Response): GenerateContentStreamResult {
- const inputStream = response.body!.pipeThrough(
- new TextDecoderStream('utf8', { fatal: true })
- );
- const responseStream =
- getResponseStream(inputStream);
+ const inputStream = response.body!.pipeThrough(new TextDecoderStream('utf8', { fatal: true }));
+ const responseStream = getResponseStream(inputStream);
const [stream1, stream2] = responseStream.tee();
return {
stream: generateResponseSequence(stream1),
- response: getResponsePromise(stream2)
+ response: getResponsePromise(stream2),
};
}
async function getResponsePromise(
- stream: ReadableStream
+ stream: ReadableStream,
): Promise {
const allResponses: GenerateContentResponse[] = [];
const reader = stream.getReader();
while (true) {
const { done, value } = await reader.read();
if (done) {
- const enhancedResponse = createEnhancedContentResponse(
- aggregateResponses(allResponses)
- );
+ const enhancedResponse = createEnhancedContentResponse(aggregateResponses(allResponses));
return enhancedResponse;
}
allResponses.push(value);
@@ -67,7 +62,7 @@ async function getResponsePromise(
}
async function* generateResponseSequence(
- stream: ReadableStream
+ stream: ReadableStream,
): AsyncGenerator {
const reader = stream.getReader();
while (true) {
@@ -86,9 +81,7 @@ async function* generateResponseSequence(
* chunks, returning a new stream that provides a single complete
* GenerateContentResponse in each iteration.
*/
-export function getResponseStream(
- inputStream: ReadableStream
-): ReadableStream {
+export function getResponseStream(inputStream: ReadableStream): ReadableStream {
const reader = inputStream.getReader();
const stream = new ReadableStream({
start(controller) {
@@ -99,10 +92,7 @@ export function getResponseStream(
if (done) {
if (currentText.trim()) {
controller.error(
- new VertexAIError(
- VertexAIErrorCode.PARSE_FAILED,
- 'Failed to parse stream'
- )
+ new VertexAIError(VertexAIErrorCode.PARSE_FAILED, 'Failed to parse stream'),
);
return;
}
@@ -120,8 +110,8 @@ export function getResponseStream(
controller.error(
new VertexAIError(
VertexAIErrorCode.PARSE_FAILED,
- `Error parsing JSON response: "${match[1]}`
- )
+ `Error parsing JSON response: "${match[1]}`,
+ ),
);
return;
}
@@ -132,7 +122,7 @@ export function getResponseStream(
return pump();
});
}
- }
+ },
});
return stream;
}
@@ -141,12 +131,10 @@ export function getResponseStream(
* Aggregates an array of `GenerateContentResponse`s into a single
* GenerateContentResponse.
*/
-export function aggregateResponses(
- responses: GenerateContentResponse[]
-): GenerateContentResponse {
+export function aggregateResponses(responses: GenerateContentResponse[]): GenerateContentResponse {
const lastResponse = responses[responses.length - 1];
const aggregatedResponse: GenerateContentResponse = {
- promptFeedback: lastResponse?.promptFeedback
+ promptFeedback: lastResponse?.promptFeedback,
};
for (const response of responses) {
if (response.candidates) {
@@ -159,17 +147,14 @@ export function aggregateResponses(
}
if (!aggregatedResponse.candidates[i]) {
aggregatedResponse.candidates[i] = {
- index: candidate.index
+ index: candidate.index,
} as GenerateContentCandidate;
}
// Keep overwriting, the last one will be final
- aggregatedResponse.candidates[i].citationMetadata =
- candidate.citationMetadata;
+ aggregatedResponse.candidates[i].citationMetadata = candidate.citationMetadata;
aggregatedResponse.candidates[i].finishReason = candidate.finishReason;
- aggregatedResponse.candidates[i].finishMessage =
- candidate.finishMessage;
- aggregatedResponse.candidates[i].safetyRatings =
- candidate.safetyRatings;
+ aggregatedResponse.candidates[i].finishMessage = candidate.finishMessage;
+ aggregatedResponse.candidates[i].safetyRatings = candidate.safetyRatings;
/**
* Candidates should always have content and parts, but this handles
@@ -179,7 +164,7 @@ export function aggregateResponses(
if (!aggregatedResponse.candidates[i].content) {
aggregatedResponse.candidates[i].content = {
role: candidate.content.role || 'user',
- parts: []
+ parts: [],
};
}
const newPart: Partial = {};
@@ -193,9 +178,7 @@ export function aggregateResponses(
if (Object.keys(newPart).length === 0) {
newPart.text = '';
}
- aggregatedResponse.candidates[i].content.parts.push(
- newPart as Part
- );
+ aggregatedResponse.candidates[i].content.parts.push(newPart as Part);
}
}
}
From 0908588b5fac20ba9c579e7cbda0fdbc3ec68ee4 Mon Sep 17 00:00:00 2001
From: russellwheatley
Date: Thu, 9 Jan 2025 12:28:12 +0000
Subject: [PATCH 010/115] initial attempt at polyfilling stream
---
packages/vertexai/lib/polyfills.ts | 8 +++++++
.../vertexai/lib/requests/stream-reader.ts | 21 ++++++++++++++++---
packages/vertexai/lib/types/polyfills.d.ts | 15 +++++++++++++
3 files changed, 41 insertions(+), 3 deletions(-)
create mode 100644 packages/vertexai/lib/polyfills.ts
create mode 100644 packages/vertexai/lib/types/polyfills.d.ts
diff --git a/packages/vertexai/lib/polyfills.ts b/packages/vertexai/lib/polyfills.ts
new file mode 100644
index 0000000000..3cc5ef1fac
--- /dev/null
+++ b/packages/vertexai/lib/polyfills.ts
@@ -0,0 +1,8 @@
+// @ts-ignore
+import { polyfill } from 'react-native-polyfill-globals/src/fetch';
+polyfill();
+
+// @ts-ignore
+import { ReadableStream as ReadableStreamPolyfill } from 'web-streams-polyfill/dist/ponyfill';
+// @ts-ignore
+globalThis.ReadableStream = ReadableStreamPolyfill;
diff --git a/packages/vertexai/lib/requests/stream-reader.ts b/packages/vertexai/lib/requests/stream-reader.ts
index cdd000d0c6..2662cb473b 100644
--- a/packages/vertexai/lib/requests/stream-reader.ts
+++ b/packages/vertexai/lib/requests/stream-reader.ts
@@ -15,6 +15,7 @@
* limitations under the License.
*/
+import { ReadableStream } from 'web-streams-polyfill';
import {
EnhancedGenerateContentResponse,
GenerateContentCandidate,
@@ -37,7 +38,21 @@ const responseLineRE = /^data\: (.*)(?:\n\n|\r\r|\r\n\r\n)/;
* @param response - Response from a fetch call
*/
export function processStream(response: Response): GenerateContentStreamResult {
- const inputStream = response.body!.pipeThrough(new TextDecoderStream('utf8', { fatal: true }));
+ const inputStream = new ReadableStream({
+ async start(controller) {
+ const reader = response.body!.getReader();
+ const decoder = new TextDecoder('utf-8');
+ while (true) {
+ const { done, value } = await reader.read();
+ if (done) {
+ controller.close();
+ break;
+ }
+ const decodedValue = decoder.decode(value, { stream: true });
+ controller.enqueue(decodedValue);
+ }
+ },
+ });
const responseStream = getResponseStream(inputStream);
const [stream1, stream2] = responseStream.tee();
return {
@@ -86,7 +101,7 @@ export function getResponseStream(inputStream: ReadableStream): Reada
const stream = new ReadableStream({
start(controller) {
let currentText = '';
- return pump();
+ return pump().then(() => undefined);
function pump(): Promise<(() => Promise) | undefined> {
return reader.read().then(({ value, done }) => {
if (done) {
@@ -105,7 +120,7 @@ export function getResponseStream(inputStream: ReadableStream): Reada
let parsedResponse: T;
while (match) {
try {
- parsedResponse = JSON.parse(match[1]);
+ parsedResponse = JSON.parse(match[1]!);
} catch (e) {
controller.error(
new VertexAIError(
diff --git a/packages/vertexai/lib/types/polyfills.d.ts b/packages/vertexai/lib/types/polyfills.d.ts
new file mode 100644
index 0000000000..06fdf29b09
--- /dev/null
+++ b/packages/vertexai/lib/types/polyfills.d.ts
@@ -0,0 +1,15 @@
+declare module 'react-native-fetch-api' {
+ export function fetch(input: RequestInfo, init?: RequestInit): Promise;
+}
+
+declare global {
+ interface RequestInit {
+ /**
+ * @description Polyfilled to enable text ReadableStream for React Native:
+ * @link https://github.com/facebook/react-native/issues/27741#issuecomment-2362901032
+ */
+ reactNative?: {
+ textStreaming: boolean;
+ };
+ }
+}
From b12d240c1443b839968758018d2c8bbaca2b3137 Mon Sep 17 00:00:00 2001
From: russellwheatley
Date: Fri, 10 Jan 2025 14:40:04 +0000
Subject: [PATCH 011/115] fix: polyfill stream for react native
---
packages/vertexai/lib/index.ts | 3 ++-
packages/vertexai/lib/polyfills.ts | 2 ++
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/packages/vertexai/lib/index.ts b/packages/vertexai/lib/index.ts
index 20ac5384a1..f6439e6abd 100644
--- a/packages/vertexai/lib/index.ts
+++ b/packages/vertexai/lib/index.ts
@@ -15,6 +15,7 @@
*
*/
+import './polyfills';
import { getApp, FirebaseApp } from '@firebase/app';
import { ModelParams, RequestOptions, VertexAIErrorCode } from './types';
import { DEFAULT_LOCATION } from './constants';
@@ -22,7 +23,6 @@ import { VertexAI, VertexAIOptions } from './public-types';
// import { ModelParams, RequestOptions, VertexAIErrorCode } from './types';
import { VertexAIError } from './errors';
import { GenerativeModel } from './models/generative-model';
-
export { ChatSession } from './methods/chat-session';
export * from './requests/schema-builder';
@@ -43,6 +43,7 @@ export function getVertexAI(app: FirebaseApp = getApp(), options?: VertexAIOptio
// const vertexProvider: Provider<'vertexAI'> = _getProvider(app, VERTEX_TYPE);
// TODO - app used to get location and later the projectId
+ // TODO - get all types from node_modules/@firebase
// return vertexProvider.getImmediate({
// identifier: options?.location || DEFAULT_LOCATION,
// });
diff --git a/packages/vertexai/lib/polyfills.ts b/packages/vertexai/lib/polyfills.ts
index 3cc5ef1fac..db76c9911a 100644
--- a/packages/vertexai/lib/polyfills.ts
+++ b/packages/vertexai/lib/polyfills.ts
@@ -6,3 +6,5 @@ polyfill();
import { ReadableStream as ReadableStreamPolyfill } from 'web-streams-polyfill/dist/ponyfill';
// @ts-ignore
globalThis.ReadableStream = ReadableStreamPolyfill;
+
+import 'text-encoding';
From a91d3a29fa24a3c97bc92d3935617b6823040288 Mon Sep 17 00:00:00 2001
From: russellwheatley
Date: Fri, 10 Jan 2025 14:40:20 +0000
Subject: [PATCH 012/115] chore: remove verbatimModuleSyntax
---
packages/vertexai/tsconfig.json | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/packages/vertexai/tsconfig.json b/packages/vertexai/tsconfig.json
index 356b26154c..b72c829b2f 100644
--- a/packages/vertexai/tsconfig.json
+++ b/packages/vertexai/tsconfig.json
@@ -21,7 +21,6 @@
"resolveJsonModule": true,
"skipLibCheck": true,
"strict": true,
- "target": "ESNext",
- "verbatimModuleSyntax": true
+ "target": "ESNext"
}
}
From c889d1436d2d42bda84debbcf29386e164c6e536 Mon Sep 17 00:00:00 2001
From: russellwheatley
Date: Fri, 10 Jan 2025 14:41:20 +0000
Subject: [PATCH 013/115] chore: use module dist and update version for TS
---
packages/vertexai/package.json | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/packages/vertexai/package.json b/packages/vertexai/package.json
index 8c0df7b430..f8c5260bf5 100644
--- a/packages/vertexai/package.json
+++ b/packages/vertexai/package.json
@@ -3,10 +3,10 @@
"version": "0.0.1",
"author": "Invertase (http://invertase.io)",
"description": "React Native Firebase - Vertex AI is a fully-managed, unified AI development platform for building and using generative AI",
- "main": "./dist/commonjs/index.js",
- "types": "./dist/typescript/commonjs/lib/index.d.ts",
+ "main": "./dist/module/index.js",
+ "types": "./dist/typescript/module/lib/index.d.ts",
"scripts": {
- "build": "genversion --semi lib/version.js",
+ "build": "genversion --semi lib/version.js && genversion --esm --semi lib/version.ts",
"build:clean": "rimraf android/build && rimraf ios/build",
"prepare": "yarn run build && bob build"
},
@@ -30,6 +30,7 @@
"access": "public"
},
"devDependencies": {
+ "@types/text-encoding": "^0",
"react-native-builder-bob": "^0.35.2",
"typescript": "^5.7.2"
},
@@ -81,5 +82,11 @@
"eslintIgnore": [
"node_modules/",
"dist/"
- ]
+ ],
+ "dependencies": {
+ "react-native-fetch-api": "^3.0.0",
+ "react-native-polyfill-globals": "^3.1.0",
+ "text-encoding": "^0.7.0",
+ "web-streams-polyfill": "^4.1.0"
+ }
}
From 8495c61f8023ecca01abecbd396b20e09cbbcc10 Mon Sep 17 00:00:00 2001
From: russellwheatley
Date: Fri, 10 Jan 2025 14:41:33 +0000
Subject: [PATCH 014/115] chore: check in version.ts
---
packages/vertexai/lib/version.ts | 2 ++
1 file changed, 2 insertions(+)
create mode 100644 packages/vertexai/lib/version.ts
diff --git a/packages/vertexai/lib/version.ts b/packages/vertexai/lib/version.ts
new file mode 100644
index 0000000000..997ce3b865
--- /dev/null
+++ b/packages/vertexai/lib/version.ts
@@ -0,0 +1,2 @@
+// Generated by genversion.
+export const version = '0.0.1';
From 200d8603d55ac280e5857f4dbf411dbb6f3ed36c Mon Sep 17 00:00:00 2001
From: russellwheatley
Date: Fri, 10 Jan 2025 14:41:47 +0000
Subject: [PATCH 015/115] get version from version.ts
---
packages/vertexai/lib/constants.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/packages/vertexai/lib/constants.ts b/packages/vertexai/lib/constants.ts
index 357e6c4e77..a9af794707 100644
--- a/packages/vertexai/lib/constants.ts
+++ b/packages/vertexai/lib/constants.ts
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-import { version } from '../package.json';
+import { version } from './version';
export const VERTEX_TYPE = 'vertexAI';
From 68e502cdff5797a5a0964f0c24cd613a7f36c39b Mon Sep 17 00:00:00 2001
From: russellwheatley
Date: Fri, 10 Jan 2025 14:42:03 +0000
Subject: [PATCH 016/115] fix: RN specific stream
---
packages/vertexai/lib/requests/request.ts | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/packages/vertexai/lib/requests/request.ts b/packages/vertexai/lib/requests/request.ts
index 058dcb8a3c..f7deb54819 100644
--- a/packages/vertexai/lib/requests/request.ts
+++ b/packages/vertexai/lib/requests/request.ts
@@ -143,8 +143,15 @@ export async function makeRequest(
const abortController = new AbortController();
fetchTimeoutId = setTimeout(() => abortController.abort(), timeoutMillis);
request.fetchOptions.signal = abortController.signal;
-
- response = await fetch(request.url, request.fetchOptions);
+ const fetchOptions = stream
+ ? {
+ ...request.fetchOptions,
+ reactNative: {
+ textStreaming: true,
+ },
+ }
+ : request.fetchOptions;
+ response = await fetch(request.url, fetchOptions);
if (!response.ok) {
let message = '';
let errorDetails;
From 30b673d59688597dabb1ba59ab44c3b5a39c5bb8 Mon Sep 17 00:00:00 2001
From: russellwheatley
Date: Thu, 16 Jan 2025 10:53:05 +0000
Subject: [PATCH 017/115] feat: allow auth and app check to be passed in
---
packages/vertexai/lib/index.ts | 26 +++++----
.../vertexai/lib/models/generative-model.ts | 5 +-
packages/vertexai/lib/requests/request.ts | 13 +++--
packages/vertexai/lib/service.ts | 18 ++----
packages/vertexai/lib/types/internal.ts | 56 +++++++++++++++++--
5 files changed, 83 insertions(+), 35 deletions(-)
diff --git a/packages/vertexai/lib/index.ts b/packages/vertexai/lib/index.ts
index f6439e6abd..850b923d45 100644
--- a/packages/vertexai/lib/index.ts
+++ b/packages/vertexai/lib/index.ts
@@ -17,12 +17,15 @@
import './polyfills';
import { getApp, FirebaseApp } from '@firebase/app';
+import { AppCheck } from '@firebase/app-check';
+import { Auth } from '@firebase/auth';
import { ModelParams, RequestOptions, VertexAIErrorCode } from './types';
import { DEFAULT_LOCATION } from './constants';
import { VertexAI, VertexAIOptions } from './public-types';
// import { ModelParams, RequestOptions, VertexAIErrorCode } from './types';
import { VertexAIError } from './errors';
import { GenerativeModel } from './models/generative-model';
+import { VertexAIService } from './service';
export { ChatSession } from './methods/chat-session';
export * from './requests/schema-builder';
@@ -36,21 +39,22 @@ export { VertexAIError };
* @public
*
* @param app - The {@link @firebase/app#FirebaseApp} to use.
+ * @param options - The {@link VertexAIOptions} to use.
+ * @param appCheck - The {@link @firebase/app-check#AppCheck} to use.
+ * @param auth - The {@link @firebase/auth#Auth} to use.
*/
-export function getVertexAI(app: FirebaseApp = getApp(), options?: VertexAIOptions): VertexAI {
- // app = getModularInstance(app);
- // Dependencies
- // const vertexProvider: Provider<'vertexAI'> = _getProvider(app, VERTEX_TYPE);
-
- // TODO - app used to get location and later the projectId
- // TODO - get all types from node_modules/@firebase
- // return vertexProvider.getImmediate({
- // identifier: options?.location || DEFAULT_LOCATION,
- // });
+export function getVertexAI(
+ app: FirebaseApp = getApp(),
+ options?: VertexAIOptions,
+ appCheck?: AppCheck,
+ auth?: Auth,
+): VertexAI {
return {
app,
location: options?.location || DEFAULT_LOCATION,
- };
+ appCheck: appCheck || null,
+ auth: auth || null,
+ } as VertexAIService;
}
/**
diff --git a/packages/vertexai/lib/models/generative-model.ts b/packages/vertexai/lib/models/generative-model.ts
index 9df5d1c4ed..111cefa427 100644
--- a/packages/vertexai/lib/models/generative-model.ts
+++ b/packages/vertexai/lib/models/generative-model.ts
@@ -77,8 +77,9 @@ export class GenerativeModel {
(vertexAI as VertexAIService).appCheck!.getToken();
}
- if ((vertexAI as VertexAIService).auth) {
- this._apiSettings.getAuthToken = () => (vertexAI as VertexAIService).auth!.getToken();
+ if ((vertexAI as VertexAIService).auth?.currentUser) {
+ this._apiSettings.getAuthToken = () =>
+ (vertexAI as VertexAIService).auth!.currentUser!.getIdToken();
}
}
if (modelParams.model.includes('/')) {
diff --git a/packages/vertexai/lib/requests/request.ts b/packages/vertexai/lib/requests/request.ts
index f7deb54819..82669a5b0f 100644
--- a/packages/vertexai/lib/requests/request.ts
+++ b/packages/vertexai/lib/requests/request.ts
@@ -84,19 +84,22 @@ export async function getHeaders(url: RequestUrl): Promise {
headers.append('x-goog-api-client', getClientHeaders());
headers.append('x-goog-api-key', url.apiSettings.apiKey);
if (url.apiSettings.getAppCheckToken) {
- const appCheckToken = await url.apiSettings.getAppCheckToken();
+ let appCheckToken;
+
+ try {
+ appCheckToken = await url.apiSettings.getAppCheckToken();
+ } catch (e) {
+ logger.warn(`Unable to obtain a valid App Check token: ${e}`);
+ }
if (appCheckToken) {
headers.append('X-Firebase-AppCheck', appCheckToken.token);
- if (appCheckToken.error) {
- logger.warn(`Unable to obtain a valid App Check token: ${appCheckToken.error.message}`);
- }
}
}
if (url.apiSettings.getAuthToken) {
const authToken = await url.apiSettings.getAuthToken();
if (authToken) {
- headers.append('Authorization', `Firebase ${authToken.accessToken}`);
+ headers.append('Authorization', `Firebase ${authToken}`);
}
}
diff --git a/packages/vertexai/lib/service.ts b/packages/vertexai/lib/service.ts
index 1c1573a926..df4295c0b6 100644
--- a/packages/vertexai/lib/service.ts
+++ b/packages/vertexai/lib/service.ts
@@ -17,28 +17,20 @@
import { FirebaseApp } from '@firebase/app';
import { VertexAI, VertexAIOptions } from './public-types';
-import {
- AppCheckInternalComponentName,
- FirebaseAppCheckInternal,
-} from '@firebase/app-check-interop-types';
-import { Provider } from '@firebase/component';
-import { FirebaseAuthInternal, FirebaseAuthInternalName } from '@firebase/auth-interop-types';
import { DEFAULT_LOCATION } from './constants';
-import { _FirebaseService } from './types/internal';
+import { _FirebaseService, InternalAppCheck, InternalAuth } from './types/internal';
export class VertexAIService implements VertexAI, _FirebaseService {
- auth: FirebaseAuthInternal | null;
- appCheck: FirebaseAppCheckInternal | null;
+ auth: InternalAuth | null;
+ appCheck: InternalAppCheck | null;
location: string;
constructor(
public app: FirebaseApp,
- authProvider?: Provider,
- appCheckProvider?: Provider,
+ auth?: InternalAuth,
+ appCheck?: InternalAppCheck,
public options?: VertexAIOptions,
) {
- const appCheck = appCheckProvider?.getImmediate({ optional: true });
- const auth = authProvider?.getImmediate({ optional: true });
this.auth = auth || null;
this.appCheck = appCheck || null;
this.location = this.options?.location || DEFAULT_LOCATION;
diff --git a/packages/vertexai/lib/types/internal.ts b/packages/vertexai/lib/types/internal.ts
index 1aa36f783f..68dbc068ac 100644
--- a/packages/vertexai/lib/types/internal.ts
+++ b/packages/vertexai/lib/types/internal.ts
@@ -14,16 +14,13 @@
* limitations under the License.
*
*/
-
-import { AppCheckTokenResult } from '@firebase/app-check-interop-types';
-import { FirebaseAuthTokenData } from '@firebase/auth-interop-types';
import { FirebaseApp } from '@firebase/app';
export interface ApiSettings {
apiKey: string;
project: string;
location: string;
- getAuthToken?: () => Promise;
+ getAuthToken?: () => Promise;
getAppCheckToken?: () => Promise;
}
@@ -39,3 +36,54 @@ export interface _FirebaseService {
*/
_delete(): Promise;
}
+
+export interface InternalAppCheck {
+ /**
+ * Requests Firebase App Check token.
+ * This method should only be used if you need to authorize requests to a non-Firebase backend.
+ * Requests to Firebase backend are authorized automatically if configured.
+ *
+ * @param forceRefresh - If true, a new Firebase App Check token is requested and the token cache is ignored.
+ * If false, the cached token is used if it exists and has not expired yet.
+ * In most cases, false should be used. True should only be used if the server explicitly returns an error, indicating a revoked token.
+ */
+ getToken(forceRefresh?: boolean): Promise;
+}
+
+interface AppCheckTokenResult {
+ /**
+ * The token string in JWT format.
+ */
+ readonly token: string;
+}
+
+export interface InternalAuth {
+ /**
+ * Returns the currently signed-in user (or null if no user signed in). See the User interface documentation for detailed usage.
+ *
+ * #### Example
+ *
+ * ```js
+ * const user = firebase.auth().currentUser;
+ * ```
+ *
+ * > It is recommended to use {@link auth#onAuthStateChanged} to track whether the user is currently signed in.
+ */
+ currentUser: User | null;
+}
+
+export interface User {
+ /**
+ * Returns the users authentication token.
+ *
+ * #### Example
+ *
+ * ```js
+ * // Force a token refresh
+ * const idToken = await firebase.auth().currentUser.getIdToken(true);
+ * ```
+ *
+ * @param forceRefresh A boolean value which forces Firebase to refresh the token.
+ */
+ getIdToken(forceRefresh?: boolean): Promise;
+}
From 7d385b017f773f2819fc3323ae8afec07a9dda0b Mon Sep 17 00:00:00 2001
From: russellwheatley
Date: Thu, 16 Jan 2025 12:44:37 +0000
Subject: [PATCH 018/115] test: write first test file
---
.../__tests__/chat-session-helpers.test.ts | 153 ++++++++++++++++++
packages/vertexai/tsconfig.json | 2 +-
2 files changed, 154 insertions(+), 1 deletion(-)
create mode 100644 packages/vertexai/__tests__/chat-session-helpers.test.ts
diff --git a/packages/vertexai/__tests__/chat-session-helpers.test.ts b/packages/vertexai/__tests__/chat-session-helpers.test.ts
new file mode 100644
index 0000000000..f96fa95d33
--- /dev/null
+++ b/packages/vertexai/__tests__/chat-session-helpers.test.ts
@@ -0,0 +1,153 @@
+/**
+ * @license
+ * Copyright 2024 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { describe, expect, it } from '@jest/globals';
+import { validateChatHistory } from '../lib/methods/chat-session-helpers';
+import { Content } from '../lib/types';
+import { FirebaseError } from '@firebase/util';
+
+describe('chat-session-helpers', () => {
+ describe('validateChatHistory', () => {
+ const TCS: Array<{ history: Content[]; isValid: boolean }> = [
+ {
+ history: [{ role: 'user', parts: [{ text: 'hi' }] }],
+ isValid: true,
+ },
+ {
+ history: [
+ {
+ role: 'user',
+ parts: [{ text: 'hi' }, { inlineData: { mimeType: 'image/jpeg', data: 'base64==' } }],
+ },
+ ],
+ isValid: true,
+ },
+ {
+ history: [
+ { role: 'user', parts: [{ text: 'hi' }] },
+ { role: 'model', parts: [{ text: 'hi' }, { text: 'hi' }] },
+ ],
+ isValid: true,
+ },
+ {
+ history: [
+ { role: 'user', parts: [{ text: 'hi' }] },
+ {
+ role: 'model',
+ parts: [{ functionCall: { name: 'greet', args: { name: 'user' } } }],
+ },
+ ],
+ isValid: true,
+ },
+ {
+ history: [
+ { role: 'user', parts: [{ text: 'hi' }] },
+ {
+ role: 'model',
+ parts: [{ functionCall: { name: 'greet', args: { name: 'user' } } }],
+ },
+ {
+ role: 'function',
+ parts: [
+ {
+ functionResponse: { name: 'greet', response: { name: 'user' } },
+ },
+ ],
+ },
+ ],
+ isValid: true,
+ },
+ {
+ history: [
+ { role: 'user', parts: [{ text: 'hi' }] },
+ {
+ role: 'model',
+ parts: [{ functionCall: { name: 'greet', args: { name: 'user' } } }],
+ },
+ {
+ role: 'function',
+ parts: [
+ {
+ functionResponse: { name: 'greet', response: { name: 'user' } },
+ },
+ ],
+ },
+ {
+ role: 'model',
+ parts: [{ text: 'hi name' }],
+ },
+ ],
+ isValid: true,
+ },
+ {
+ //@ts-expect-error
+ history: [{ role: 'user', parts: '' }],
+ isValid: false,
+ },
+ {
+ //@ts-expect-error
+ history: [{ role: 'user' }],
+ isValid: false,
+ },
+ {
+ history: [{ role: 'user', parts: [] }],
+ isValid: false,
+ },
+ {
+ history: [{ role: 'model', parts: [{ text: 'hi' }] }],
+ isValid: false,
+ },
+ {
+ history: [
+ {
+ role: 'function',
+ parts: [
+ {
+ functionResponse: { name: 'greet', response: { name: 'user' } },
+ },
+ ],
+ },
+ ],
+ isValid: false,
+ },
+ {
+ history: [
+ { role: 'user', parts: [{ text: 'hi' }] },
+ { role: 'user', parts: [{ text: 'hi' }] },
+ ],
+ isValid: false,
+ },
+ {
+ history: [
+ { role: 'user', parts: [{ text: 'hi' }] },
+ { role: 'model', parts: [{ text: 'hi' }] },
+ { role: 'model', parts: [{ text: 'hi' }] },
+ ],
+ isValid: false,
+ },
+ ];
+ TCS.forEach((tc, index) => {
+ it(`case ${index}`, () => {
+ const fn = (): void => validateChatHistory(tc.history);
+ if (tc.isValid) {
+ expect(fn).not.toThrow();
+ } else {
+ expect(fn).toThrow(FirebaseError);
+ }
+ });
+ });
+ });
+});
diff --git a/packages/vertexai/tsconfig.json b/packages/vertexai/tsconfig.json
index b72c829b2f..95dd21071e 100644
--- a/packages/vertexai/tsconfig.json
+++ b/packages/vertexai/tsconfig.json
@@ -10,6 +10,7 @@
"ESNext"
],
"module": "ESNext",
+ "target": "ESNext",
"moduleResolution": "Bundler",
"noFallthroughCasesInSwitch": true,
"noImplicitReturns": true,
@@ -21,6 +22,5 @@
"resolveJsonModule": true,
"skipLibCheck": true,
"strict": true,
- "target": "ESNext"
}
}
From 08b3ce194bd947c1a6bfce5bbad8603b2c78247b Mon Sep 17 00:00:00 2001
From: russellwheatley
Date: Fri, 17 Jan 2025 10:55:19 +0000
Subject: [PATCH 019/115] test: chat session
---
.../vertexai/__tests__/chat-session.test.ts | 100 ++++++++++++++++++
1 file changed, 100 insertions(+)
create mode 100644 packages/vertexai/__tests__/chat-session.test.ts
diff --git a/packages/vertexai/__tests__/chat-session.test.ts b/packages/vertexai/__tests__/chat-session.test.ts
new file mode 100644
index 0000000000..cd96aa32e6
--- /dev/null
+++ b/packages/vertexai/__tests__/chat-session.test.ts
@@ -0,0 +1,100 @@
+/**
+ * @license
+ * Copyright 2024 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { describe, expect, it, afterEach, jest } from '@jest/globals';
+
+import * as generateContentMethods from '../lib/methods/generate-content';
+import { GenerateContentStreamResult } from '../lib/types';
+import { ChatSession } from '../lib/methods/chat-session';
+import { ApiSettings } from '../lib/types/internal';
+import { RequestOptions } from '../lib/types/requests';
+
+const fakeApiSettings: ApiSettings = {
+ apiKey: 'key',
+ project: 'my-project',
+ location: 'us-central1',
+};
+
+const requestOptions: RequestOptions = {
+ timeout: 1000,
+};
+
+describe('ChatSession', () => {
+ afterEach(() => {
+ jest.restoreAllMocks();
+ });
+
+ describe('sendMessage()', () => {
+ it('generateContent errors should be catchable', async () => {
+ const generateContentStub = jest
+ .spyOn(generateContentMethods, 'generateContent')
+ .mockRejectedValue('generateContent failed');
+
+ const chatSession = new ChatSession(fakeApiSettings, 'a-model', {}, requestOptions);
+
+ await expect(chatSession.sendMessage('hello')).rejects.toMatch(/generateContent failed/);
+
+ expect(generateContentStub).toHaveBeenCalledWith(
+ fakeApiSettings,
+ 'a-model',
+ expect.anything(),
+ requestOptions,
+ );
+ });
+ });
+
+ describe('sendMessageStream()', () => {
+ it('generateContentStream errors should be catchable', async () => {
+ jest.useFakeTimers();
+ const consoleStub = jest.spyOn(console, 'error').mockImplementation(() => {});
+ const generateContentStreamStub = jest
+ .spyOn(generateContentMethods, 'generateContentStream')
+ .mockRejectedValue('generateContentStream failed');
+ const chatSession = new ChatSession(fakeApiSettings, 'a-model', {}, requestOptions);
+ await expect(chatSession.sendMessageStream('hello')).rejects.toMatch(
+ /generateContentStream failed/,
+ );
+ expect(generateContentStreamStub).toHaveBeenCalledWith(
+ fakeApiSettings,
+ 'a-model',
+ expect.anything(),
+ requestOptions,
+ );
+ jest.runAllTimers();
+ expect(consoleStub).not.toHaveBeenCalled();
+ jest.useRealTimers();
+ });
+
+ it('downstream sendPromise errors should log but not throw', async () => {
+ const consoleStub = jest.spyOn(console, 'error').mockImplementation(() => {});
+ // make response undefined so that response.candidates errors
+ const generateContentStreamStub = jest
+ .spyOn(generateContentMethods, 'generateContentStream')
+ .mockResolvedValue({} as unknown as GenerateContentStreamResult);
+ const chatSession = new ChatSession(fakeApiSettings, 'a-model', {}, requestOptions);
+ await chatSession.sendMessageStream('hello');
+ expect(generateContentStreamStub).toHaveBeenCalledWith(
+ fakeApiSettings,
+ 'a-model',
+ expect.anything(),
+ requestOptions,
+ );
+ // wait for the console.error to be called, due to number of promises in the chain
+ await new Promise(resolve => setTimeout(resolve, 100));
+ expect(consoleStub).toHaveBeenCalledTimes(1);
+ });
+ });
+});
From 788a667eac6c1aad10fb05439b4e4e02d5a6471b Mon Sep 17 00:00:00 2001
From: russellwheatley
Date: Fri, 17 Jan 2025 10:55:28 +0000
Subject: [PATCH 020/115] initial count token
---
.../vertexai/__tests__/count-tokens.test.ts | 106 ++++++++++++++++++
1 file changed, 106 insertions(+)
create mode 100644 packages/vertexai/__tests__/count-tokens.test.ts
diff --git a/packages/vertexai/__tests__/count-tokens.test.ts b/packages/vertexai/__tests__/count-tokens.test.ts
new file mode 100644
index 0000000000..fd4b99e1e0
--- /dev/null
+++ b/packages/vertexai/__tests__/count-tokens.test.ts
@@ -0,0 +1,106 @@
+/**
+ * @license
+ * Copyright 2024 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { expect, use } from 'chai';
+import { match, restore, stub } from 'sinon';
+import sinonChai from 'sinon-chai';
+import chaiAsPromised from 'chai-as-promised';
+import { getMockResponse } from '../../test-utils/mock-response';
+import * as request from '../requests/request';
+import { countTokens } from './count-tokens';
+import { CountTokensRequest } from '../types';
+import { ApiSettings } from '../types/internal';
+import { Task } from '../requests/request';
+
+use(sinonChai);
+use(chaiAsPromised);
+
+const fakeApiSettings: ApiSettings = {
+ apiKey: 'key',
+ project: 'my-project',
+ location: 'us-central1'
+};
+
+const fakeRequestParams: CountTokensRequest = {
+ contents: [{ parts: [{ text: 'hello' }], role: 'user' }]
+};
+
+describe('countTokens()', () => {
+ afterEach(() => {
+ restore();
+ });
+ it('total tokens', async () => {
+ const mockResponse = getMockResponse('unary-success-total-tokens.json');
+ const makeRequestStub = stub(request, 'makeRequest').resolves(
+ mockResponse as Response
+ );
+ const result = await countTokens(
+ fakeApiSettings,
+ 'model',
+ fakeRequestParams
+ );
+ expect(result.totalTokens).to.equal(6);
+ expect(result.totalBillableCharacters).to.equal(16);
+ expect(makeRequestStub).to.be.calledWith(
+ 'model',
+ Task.COUNT_TOKENS,
+ fakeApiSettings,
+ false,
+ match((value: string) => {
+ return value.includes('contents');
+ }),
+ undefined
+ );
+ });
+ it('total tokens no billable characters', async () => {
+ const mockResponse = getMockResponse(
+ 'unary-success-no-billable-characters.json'
+ );
+ const makeRequestStub = stub(request, 'makeRequest').resolves(
+ mockResponse as Response
+ );
+ const result = await countTokens(
+ fakeApiSettings,
+ 'model',
+ fakeRequestParams
+ );
+ expect(result.totalTokens).to.equal(258);
+ expect(result).to.not.have.property('totalBillableCharacters');
+ expect(makeRequestStub).to.be.calledWith(
+ 'model',
+ Task.COUNT_TOKENS,
+ fakeApiSettings,
+ false,
+ match((value: string) => {
+ return value.includes('contents');
+ }),
+ undefined
+ );
+ });
+ it('model not found', async () => {
+ const mockResponse = getMockResponse('unary-failure-model-not-found.json');
+ const mockFetch = stub(globalThis, 'fetch').resolves({
+ ok: false,
+ status: 404,
+ json: mockResponse.json
+ } as Response);
+ await expect(
+ countTokens(fakeApiSettings, 'model', fakeRequestParams)
+ ).to.be.rejectedWith(/404.*not found/);
+ expect(mockFetch).to.be.called;
+ });
+});
From 76ae3af25dd4611e8d9d8efa0d862e5e3b09cbb3 Mon Sep 17 00:00:00 2001
From: russellwheatley
Date: Fri, 17 Jan 2025 11:44:54 +0000
Subject: [PATCH 021/115] test utils
---
.../__tests__/test-utils/base64cat.ts | 19 +++++
.../vertexai/__tests__/test-utils/cat.jpeg | Bin 0 -> 35160 bytes
.../vertexai/__tests__/test-utils/cat.png | Bin 0 -> 142387 bytes
.../__tests__/test-utils/mock-response.ts | 65 ++++++++++++++++++
4 files changed, 84 insertions(+)
create mode 100644 packages/vertexai/__tests__/test-utils/base64cat.ts
create mode 100644 packages/vertexai/__tests__/test-utils/cat.jpeg
create mode 100644 packages/vertexai/__tests__/test-utils/cat.png
create mode 100644 packages/vertexai/__tests__/test-utils/mock-response.ts
diff --git a/packages/vertexai/__tests__/test-utils/base64cat.ts b/packages/vertexai/__tests__/test-utils/base64cat.ts
new file mode 100644
index 0000000000..45325a1bf5
--- /dev/null
+++ b/packages/vertexai/__tests__/test-utils/base64cat.ts
@@ -0,0 +1,19 @@
+/**
+ * @license
+ * Copyright 2024 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export const base64Cat =
+ 'iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAABJWlDQ1BrQ0dDb2xvclNwYWNlQWRvYmVSR0IxOTk4AAAokWNgYFJILCjIYRJgYMjNKykKcndSiIiMUmB/zsDNwAnE2gwGicnFBY4BAT4MQACjUcG3awyMIPqyLsgsTHm8gCsltTgZSP8B4uzkgqISBgbGDCBbubykAMTuAbJFkrLB7AUgdhHQgUD2FhA7HcI+AVYDYd8BqwkJcgayPwDZfElgNhPILr50CFsAxIbaCwKCjin5SakKIN9rGFpaWmiS6AeCoCS1ogREO+cXVBZlpmeUKDgCQypVwTMvWU9HwcjAyJiBARTuENWfA8HhySh2BiGGAAixORIMDP5LGRhY/iDETHoZGBboMDDwT0WIqRkyMAjoMzDsm5NcWlQGNYaRCWgnIT4AXxVKdgMmGHwAAAFQZVhJZk1NACoAAAAIAAkBDgACAAAARwAAAHoBEgADAAAAAQABAAABGgAFAAAAAQAAAMIBGwAFAAAAAQAAAMoBKAADAAAAAQACAAABMQACAAAACwAAANIBMgACAAAAFAAAAN6CmAACAAAAEwAAAPKHaQAEAAAAAQAAAQYAAAAAUGhvdG9ncmFwaCBmcm9tIFdhbHRlciBDaGFuZG9oYTogVGhlIENhdCBQaG90b2dyYXBoZXIgKEFwZXJ0dXJlLCAyMDE1KQAAAAABLAAAAAEAAAEsAAAAAVBob3RvU2NhcGUAADIwMTU6MDY6MTggMTE6MTM6NTMAwqkgV2FsdGVyIENoYW5kb2hhAAAABJAAAAcAAAAEMDIyMZAEAAIAAAAUAAABPKACAAQAAAABAAABAKADAAQAAAABAAABAAAAAAAyMDE1OjA0OjAxIDE1OjE3OjAzALUWG8IAAAAJcEhZcwAALiMAAC4jAXilP3YAADtdaVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJYTVAgQ29yZSA2LjAuMCI+CiAgIDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+CiAgICAgIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICAgICAgICAgIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIgogICAgICAgICAgICB4bWxuczp4bXBSaWdodHM9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9yaWdodHMvIgogICAgICAgICAgICB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIgogICAgICAgICAgICB4bWxuczpzdEV2dD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlRXZlbnQjIgogICAgICAgICAgICB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIKICAgICAgICAgICAgeG1sbnM6eHdudj0iaHR0cDovL25zLnhpbmV0LmNvbS9ucy94aW5ldHNjaGVtYSMiCiAgICAgICAgICAgIHhtbG5zOnBob3Rvc2hvcD0iaHR0cDovL25zLmFkb2JlLmNvbS9waG90b3Nob3AvMS4wLyI+CiAgICAgICAgIDxkYzpmb3JtYXQ+aW1hZ2UvdGlmZjwvZGM6Zm9ybWF0PgogICAgICAgICA8ZGM6ZGVzY3JpcHRpb24+CiAgICAgICAgICAgIDxyZGY6QWx0PgogICAgICAgICAgICAgICA8cmRmOmxpIHhtbDpsYW5nPSJ4LWRlZmF1bHQiPlBob3RvZ3JhcGggZnJvbSBXYWx0ZXIgQ2hhbmRvaGE6IFRoZSBDYXQgUGhvdG9ncmFwaGVyIChBcGVydHVyZSwgMjAxNSk8L3JkZjpsaT4KICAgICAgICAgICAgPC9yZGY6QWx0PgogICAgICAgICA8L2RjOmRlc2NyaXB0aW9uPgogICAgICAgICA8ZGM6cmlnaHRzPgogICAgICAgICAgICA8cmRmOkFsdD4KICAgICAgICAgICAgICAgPHJkZjpsaSB4bWw6bGFuZz0ieC1kZWZhdWx0Ij7CqSBXYWx0ZXIgQ2hhbmRvaGE8L3JkZjpsaT4KICAgICAgICAgICAgPC9yZGY6QWx0PgogICAgICAgICA8L2RjOnJpZ2h0cz4KICAgICAgICAgPHRpZmY6UmVzb2x1dGlvblVuaXQ+MjwvdGlmZjpSZXNvbHV0aW9uVW5pdD4KICAgICAgICAgPHRpZmY6Q29tcHJlc3Npb24+MTwvdGlmZjpDb21wcmVzc2lvbj4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHRpZmY6WVJlc29sdXRpb24+MzAwPC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpYUmVzb2x1dGlvbj4zMDA8L3RpZmY6WFJlc29sdXRpb24+CiAgICAgICAgIDxleGlmOlBpeGVsWURpbWVuc2lvbj4zMDU3PC9leGlmOlBpeGVsWURpbWVuc2lvbj4KICAgICAgICAgPGV4aWY6RXhpZlZlcnNpb24+MDIyMTwvZXhpZjpFeGlmVmVyc2lvbj4KICAgICAgICAgPGV4aWY6Q29sb3JTcGFjZT42NTUzNTwvZXhpZjpDb2xvclNwYWNlPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+MjE3MzwvZXhpZjpQaXhlbFhEaW1lbnNpb24+CiAgICAgICAgIDx4bXBSaWdodHM6TWFya2VkPlRydWU8L3htcFJpZ2h0czpNYXJrZWQ+CiAgICAgICAgIDx4bXA6Q3JlYXRvclRvb2w+UGhvdG9TY2FwZTwveG1wOkNyZWF0b3JUb29sPgogICAgICAgICA8eG1wOlJhdGluZz4xPC94bXA6UmF0aW5nPgogICAgICAgICA8eG1wOk1ldGFkYXRhRGF0ZT4yMDE1LTA2LTE4VDExOjEzOjUzLTA0OjAwPC94bXA6TWV0YWRhdGFEYXRlPgogICAgICAgICA8eG1wOkNyZWF0ZURhdGU+MjAxNS0wNC0wMVQxNToxNzowMy0wNDowMDwveG1wOkNyZWF0ZURhdGU+CiAgICAgICAgIDx4bXA6TGFiZWw+QXBwcm92ZWQ8L3htcDpMYWJlbD4KICAgICAgICAgPHhtcDpNb2RpZnlEYXRlPjIwMTUtMDYtMThUMTE6MTM6NTMtMDQ6MDA8L3htcDpNb2RpZnlEYXRlPgogICAgICAgICA8eG1wTU06SGlzdG9yeT4KICAgICAgICAgICAgPHJkZjpTZXE+CiAgICAgICAgICAgICAgIDxyZGY6bGkgcmRmOnBhcnNlVHlwZT0iUmVzb3VyY2UiPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6c29mdHdhcmVBZ2VudD5BZG9iZSBQaG90b3Nob3AgQ1M1LjEgTWFjaW50b3NoPC9zdEV2dDpzb2Z0d2FyZUFnZW50PgogICAgICAgICAgICAgICAgICA8c3RFdnQ6d2hlbj4yMDE1LTA0LTAxVDE1OjE3OjAzLTA0OjAwPC9zdEV2dDp3aGVuPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6aW5zdGFuY2VJRD54bXAuaWlkOkQ2NDkzMDk2MzgyNzY4MTE4NzFGRDg0Mjk3MDE2Mjk3PC9zdEV2dDppbnN0YW5jZUlEPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6YWN0aW9uPmNyZWF0ZWQ8L3N0RXZ0OmFjdGlvbj4KICAgICAgICAgICAgICAgPC9yZGY6bGk+CiAgICAgICAgICAgICAgIDxyZGY6bGkgcmRmOnBhcnNlVHlwZT0iUmVzb3VyY2UiPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6c29mdHdhcmVBZ2VudD5BZG9iZSBQaG90b3Nob3AgQ0MgKE1hY2ludG9zaCk8L3N0RXZ0OnNvZnR3YXJlQWdlbnQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpjaGFuZ2VkPi88L3N0RXZ0OmNoYW5nZWQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDp3aGVuPjIwMTUtMDQtMDFUMTg6NTg6MDEtMDQ6MDA8L3N0RXZ0OndoZW4+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDppbnN0YW5jZUlEPnhtcC5paWQ6YTI2NDlkMWMtM2YzNy00YzVlLWFmNGMtN2MxMDg1ZTc4Yjc5PC9zdEV2dDppbnN0YW5jZUlEPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6YWN0aW9uPnNhdmVkPC9zdEV2dDphY3Rpb24+CiAgICAgICAgICAgICAgIDwvcmRmOmxpPgogICAgICAgICAgICAgICA8cmRmOmxpIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmFjdGlvbj5jb252ZXJ0ZWQ8L3N0RXZ0OmFjdGlvbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnBhcmFtZXRlcnM+ZnJvbSBpbWFnZS90aWZmIHRvIGltYWdlL2Vwc2Y8L3N0RXZ0OnBhcmFtZXRlcnM+CiAgICAgICAgICAgICAgIDwvcmRmOmxpPgogICAgICAgICAgICAgICA8cmRmOmxpIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmFjdGlvbj5kZXJpdmVkPC9zdEV2dDphY3Rpb24+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpwYXJhbWV0ZXJzPmNvbnZlcnRlZCBmcm9tIGltYWdlL3RpZmYgdG8gaW1hZ2UvZXBzZjwvc3RFdnQ6cGFyYW1ldGVycz4KICAgICAgICAgICAgICAgPC9yZGY6bGk+CiAgICAgICAgICAgICAgIDxyZGY6bGkgcmRmOnBhcnNlVHlwZT0iUmVzb3VyY2UiPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6c29mdHdhcmVBZ2VudD5BZG9iZSBQaG90b3Nob3AgQ0MgKE1hY2ludG9zaCk8L3N0RXZ0OnNvZnR3YXJlQWdlbnQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpjaGFuZ2VkPi88L3N0RXZ0OmNoYW5nZWQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDp3aGVuPjIwMTUtMDQtMDFUMTg6NTg6MDEtMDQ6MDA8L3N0RXZ0OndoZW4+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDppbnN0YW5jZUlEPnhtcC5paWQ6OGEwOTVhMjMtNTBlMS00ZDA3LWI0YjctNGNhNDA4YzVlODcyPC9zdEV2dDppbnN0YW5jZUlEPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6YWN0aW9uPnNhdmVkPC9zdEV2dDphY3Rpb24+CiAgICAgICAgICAgICAgIDwvcmRmOmxpPgogICAgICAgICAgICAgICA8cmRmOmxpIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnNvZnR3YXJlQWdlbnQ+QWRvYmUgUGhvdG9zaG9wIENDIChNYWNpbnRvc2gpPC9zdEV2dDpzb2Z0d2FyZUFnZW50PgogICAgICAgICAgICAgICAgICA8c3RFdnQ6Y2hhbmdlZD4vPC9zdEV2dDpjaGFuZ2VkPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6d2hlbj4yMDE1LTA0LTAxVDE5OjQ0OjQ2LTA0OjAwPC9zdEV2dDp3aGVuPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6aW5zdGFuY2VJRD54bXAuaWlkOjlkYzRhZDAyLTgwMzItNDMyZS05YjhlLTk1YThlMTQ1YzJkMDwvc3RFdnQ6aW5zdGFuY2VJRD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmFjdGlvbj5zYXZlZDwvc3RFdnQ6YWN0aW9uPgogICAgICAgICAgICAgICA8L3JkZjpsaT4KICAgICAgICAgICAgICAgPHJkZjpsaSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDphY3Rpb24+Y29udmVydGVkPC9zdEV2dDphY3Rpb24+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpwYXJhbWV0ZXJzPmZyb20gaW1hZ2UvZXBzZiB0byBpbWFnZS90aWZmPC9zdEV2dDpwYXJhbWV0ZXJzPgogICAgICAgICAgICAgICA8L3JkZjpsaT4KICAgICAgICAgICAgICAgPHJkZjpsaSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDphY3Rpb24+ZGVyaXZlZDwvc3RFdnQ6YWN0aW9uPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6cGFyYW1ldGVycz5jb252ZXJ0ZWQgZnJvbSBpbWFnZS9lcHNmIHRvIGltYWdlL3RpZmY8L3N0RXZ0OnBhcmFtZXRlcnM+CiAgICAgICAgICAgICAgIDwvcmRmOmxpPgogICAgICAgICAgICAgICA8cmRmOmxpIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnNvZnR3YXJlQWdlbnQ+QWRvYmUgUGhvdG9zaG9wIENDIChNYWNpbnRvc2gpPC9zdEV2dDpzb2Z0d2FyZUFnZW50PgogICAgICAgICAgICAgICAgICA8c3RFdnQ6Y2hhbmdlZD4vPC9zdEV2dDpjaGFuZ2VkPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6d2hlbj4yMDE1LTA0LTAxVDE5OjQ0OjQ2LTA0OjAwPC9zdEV2dDp3aGVuPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6aW5zdGFuY2VJRD54bXAuaWlkOjRkZTAwN2U3LTk5MWUtNDc5MS1hOTZkLTE5ZmVhMDllNWI4NTwvc3RFdnQ6aW5zdGFuY2VJRD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmFjdGlvbj5zYXZlZDwvc3RFdnQ6YWN0aW9uPgogICAgICAgICAgICAgICA8L3JkZjpsaT4KICAgICAgICAgICAgICAgPHJkZjpsaSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpzb2Z0d2FyZUFnZW50PkFkb2JlIFBob3Rvc2hvcCBDQyAoTWFjaW50b3NoKTwvc3RFdnQ6c29mdHdhcmVBZ2VudD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmNoYW5nZWQ+Lzwvc3RFdnQ6Y2hhbmdlZD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OndoZW4+MjAxNS0wNC0wMVQyMDo0Njo1Ni0wNDowMDwvc3RFdnQ6d2hlbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0Omluc3RhbmNlSUQ+eG1wLmlpZDowMjMyZmIxZC1jYjQ0LTQwOGYtYWE2MC04N2U3MDYyMGNhYmM8L3N0RXZ0Omluc3RhbmNlSUQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDphY3Rpb24+c2F2ZWQ8L3N0RXZ0OmFjdGlvbj4KICAgICAgICAgICAgICAgPC9yZGY6bGk+CiAgICAgICAgICAgICAgIDxyZGY6bGkgcmRmOnBhcnNlVHlwZT0iUmVzb3VyY2UiPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6c29mdHdhcmVBZ2VudD5BZG9iZSBQaG90b3Nob3AgQ1M1LjEgV2luZG93czwvc3RFdnQ6c29mdHdhcmVBZ2VudD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmNoYW5nZWQ+Lzwvc3RFdnQ6Y2hhbmdlZD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OndoZW4+MjAxNS0wNC0xOVQwMDoxODozMy0wNDowMDwvc3RFdnQ6d2hlbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0Omluc3RhbmNlSUQ+eG1wLmlpZDpCOUM3OENGNDQ2RTZFNDExOTRFQzkzQjJERjdGRjg2NTwvc3RFdnQ6aW5zdGFuY2VJRD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmFjdGlvbj5zYXZlZDwvc3RFdnQ6YWN0aW9uPgogICAgICAgICAgICAgICA8L3JkZjpsaT4KICAgICAgICAgICAgICAgPHJkZjpsaSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDphY3Rpb24+Y29udmVydGVkPC9zdEV2dDphY3Rpb24+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpwYXJhbWV0ZXJzPmZyb20gaW1hZ2UvdGlmZiB0byBhcHBsaWNhdGlvbi92bmQuYWRvYmUucGhvdG9zaG9wPC9zdEV2dDpwYXJhbWV0ZXJzPgogICAgICAgICAgICAgICA8L3JkZjpsaT4KICAgICAgICAgICAgICAgPHJkZjpsaSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDphY3Rpb24+ZGVyaXZlZDwvc3RFdnQ6YWN0aW9uPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6cGFyYW1ldGVycz5jb252ZXJ0ZWQgZnJvbSBpbWFnZS90aWZmIHRvIGFwcGxpY2F0aW9uL3ZuZC5hZG9iZS5waG90b3Nob3A8L3N0RXZ0OnBhcmFtZXRlcnM+CiAgICAgICAgICAgICAgIDwvcmRmOmxpPgogICAgICAgICAgICAgICA8cmRmOmxpIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnNvZnR3YXJlQWdlbnQ+QWRvYmUgUGhvdG9zaG9wIENTNS4xIFdpbmRvd3M8L3N0RXZ0OnNvZnR3YXJlQWdlbnQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpjaGFuZ2VkPi88L3N0RXZ0OmNoYW5nZWQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDp3aGVuPjIwMTUtMDQtMTlUMDA6MTg6MzMtMDQ6MDA8L3N0RXZ0OndoZW4+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDppbnN0YW5jZUlEPnhtcC5paWQ6QkFDNzhDRjQ0NkU2RTQxMTk0RUM5M0IyREY3RkY4NjU8L3N0RXZ0Omluc3RhbmNlSUQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDphY3Rpb24+c2F2ZWQ8L3N0RXZ0OmFjdGlvbj4KICAgICAgICAgICAgICAgPC9yZGY6bGk+CiAgICAgICAgICAgICAgIDxyZGY6bGkgcmRmOnBhcnNlVHlwZT0iUmVzb3VyY2UiPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6c29mdHdhcmVBZ2VudD5BZG9iZSBQaG90b3Nob3AgQ1M1LjEgV2luZG93czwvc3RFdnQ6c29mdHdhcmVBZ2VudD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmNoYW5nZWQ+Lzwvc3RFdnQ6Y2hhbmdlZD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OndoZW4+MjAxNS0wNC0xOVQxMjo0Mjo1OC0wNDowMDwvc3RFdnQ6d2hlbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0Omluc3RhbmNlSUQ+eG1wLmlpZDowNUZDQzI0NUIxRTZFNDExQjVCMEU3QTI0NTYyMUZGNjwvc3RFdnQ6aW5zdGFuY2VJRD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmFjdGlvbj5zYXZlZDwvc3RFdnQ6YWN0aW9uPgogICAgICAgICAgICAgICA8L3JkZjpsaT4KICAgICAgICAgICAgICAgPHJkZjpsaSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpzb2Z0d2FyZUFnZW50PkFkb2JlIFBob3Rvc2hvcCBDUzUuMSBXaW5kb3dzPC9zdEV2dDpzb2Z0d2FyZUFnZW50PgogICAgICAgICAgICAgICAgICA8c3RFdnQ6Y2hhbmdlZD4vPC9zdEV2dDpjaGFuZ2VkPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6d2hlbj4yMDE1LTA0LTE5VDEyOjQzOjMwLTA0OjAwPC9zdEV2dDp3aGVuPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6aW5zdGFuY2VJRD54bXAuaWlkOjA4RkNDMjQ1QjFFNkU0MTFCNUIwRTdBMjQ1NjIxRkY2PC9zdEV2dDppbnN0YW5jZUlEPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6YWN0aW9uPnNhdmVkPC9zdEV2dDphY3Rpb24+CiAgICAgICAgICAgICAgIDwvcmRmOmxpPgogICAgICAgICAgICAgICA8cmRmOmxpIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmFjdGlvbj5jb252ZXJ0ZWQ8L3N0RXZ0OmFjdGlvbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnBhcmFtZXRlcnM+ZnJvbSBhcHBsaWNhdGlvbi92bmQuYWRvYmUucGhvdG9zaG9wIHRvIGltYWdlL3RpZmY8L3N0RXZ0OnBhcmFtZXRlcnM+CiAgICAgICAgICAgICAgIDwvcmRmOmxpPgogICAgICAgICAgICAgICA8cmRmOmxpIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmFjdGlvbj5kZXJpdmVkPC9zdEV2dDphY3Rpb24+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpwYXJhbWV0ZXJzPmNvbnZlcnRlZCBmcm9tIGFwcGxpY2F0aW9uL3ZuZC5hZG9iZS5waG90b3Nob3AgdG8gaW1hZ2UvdGlmZjwvc3RFdnQ6cGFyYW1ldGVycz4KICAgICAgICAgICAgICAgPC9yZGY6bGk+CiAgICAgICAgICAgICAgIDxyZGY6bGkgcmRmOnBhcnNlVHlwZT0iUmVzb3VyY2UiPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6c29mdHdhcmVBZ2VudD5BZG9iZSBQaG90b3Nob3AgQ1M1LjEgV2luZG93czwvc3RFdnQ6c29mdHdhcmVBZ2VudD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmNoYW5nZWQ+Lzwvc3RFdnQ6Y2hhbmdlZD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OndoZW4+MjAxNS0wNC0xOVQxMjo0MzozMC0wNDowMDwvc3RFdnQ6d2hlbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0Omluc3RhbmNlSUQ+eG1wLmlpZDowOUZDQzI0NUIxRTZFNDExQjVCMEU3QTI0NTYyMUZGNjwvc3RFdnQ6aW5zdGFuY2VJRD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmFjdGlvbj5zYXZlZDwvc3RFdnQ6YWN0aW9uPgogICAgICAgICAgICAgICA8L3JkZjpsaT4KICAgICAgICAgICAgICAgPHJkZjpsaSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpzb2Z0d2FyZUFnZW50PkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE0IChNYWNpbnRvc2gpPC9zdEV2dDpzb2Z0d2FyZUFnZW50PgogICAgICAgICAgICAgICAgICA8c3RFdnQ6Y2hhbmdlZD4vPC9zdEV2dDpjaGFuZ2VkPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6d2hlbj4yMDE1LTA0LTIxVDEwOjQ4OjM1LTA0OjAwPC9zdEV2dDp3aGVuPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6aW5zdGFuY2VJRD54bXAuaWlkOmUzODZlNjQ4LWZmNjYtNDA5NC04NWEyLWY2NjgxZTRiM2I4Mjwvc3RFdnQ6aW5zdGFuY2VJRD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmFjdGlvbj5zYXZlZDwvc3RFdnQ6YWN0aW9uPgogICAgICAgICAgICAgICA8L3JkZjpsaT4KICAgICAgICAgICAgICAgPHJkZjpsaSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpzb2Z0d2FyZUFnZW50PkFkb2JlIEJyaWRnZSBDQyAoTWFjaW50b3NoKTwvc3RFdnQ6c29mdHdhcmVBZ2VudD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmNoYW5nZWQ+L21ldGFkYXRhPC9zdEV2dDpjaGFuZ2VkPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6d2hlbj4yMDE1LTA0LTIzVDIxOjEwOjQ2LTA0OjAwPC9zdEV2dDp3aGVuPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6aW5zdGFuY2VJRD54bXAuaWlkOmIwZmJjMzZkLThhMjgtNDU4NC05NTlkLTk5NjFmZDEyMDA5Mjwvc3RFdnQ6aW5zdGFuY2VJRD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmFjdGlvbj5zYXZlZDwvc3RFdnQ6YWN0aW9uPgogICAgICAgICAgICAgICA8L3JkZjpsaT4KICAgICAgICAgICAgICAgPHJkZjpsaSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpzb2Z0d2FyZUFnZW50PkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE0IChNYWNpbnRvc2gpPC9zdEV2dDpzb2Z0d2FyZUFnZW50PgogICAgICAgICAgICAgICAgICA8c3RFdnQ6Y2hhbmdlZD4vPC9zdEV2dDpjaGFuZ2VkPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6d2hlbj4yMDE1LTA0LTIzVDIyOjIyOjIzLTA0OjAwPC9zdEV2dDp3aGVuPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6aW5zdGFuY2VJRD54bXAuaWlkOmM1MzNhNjRlLTk0OTktNDMzOS05MjM4LThhOGY0Nzc3NzQ3YTwvc3RFdnQ6aW5zdGFuY2VJRD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmFjdGlvbj5zYXZlZDwvc3RFdnQ6YWN0aW9uPgogICAgICAgICAgICAgICA8L3JkZjpsaT4KICAgICAgICAgICAgICAgPHJkZjpsaSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpzb2Z0d2FyZUFnZW50PkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE0IChNYWNpbnRvc2gpPC9zdEV2dDpzb2Z0d2FyZUFnZW50PgogICAgICAgICAgICAgICAgICA8c3RFdnQ6Y2hhbmdlZD4vPC9zdEV2dDpjaGFuZ2VkPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6d2hlbj4yMDE1LTA0LTIzVDIyOjIzOjQyLTA0OjAwPC9zdEV2dDp3aGVuPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6aW5zdGFuY2VJRD54bXAuaWlkOmRiMjlmZTVlLWQ2ZDAtNDBjZi04Y2RkLTBkYTU2NDgwMTU2YTwvc3RFdnQ6aW5zdGFuY2VJRD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmFjdGlvbj5zYXZlZDwvc3RFdnQ6YWN0aW9uPgogICAgICAgICAgICAgICA8L3JkZjpsaT4KICAgICAgICAgICAgICAgPHJkZjpsaSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpzb2Z0d2FyZUFnZW50PkFkb2JlIFBob3Rvc2hvcCBDYW1lcmEgUmF3IDguODwvc3RFdnQ6c29mdHdhcmVBZ2VudD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmNoYW5nZWQ+L21ldGFkYXRhPC9zdEV2dDpjaGFuZ2VkPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6d2hlbj4yMDE1LTA0LTIzVDIyOjMyOjMwLTA0OjAwPC9zdEV2dDp3aGVuPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6aW5zdGFuY2VJRD54bXAuaWlkOmRkMzFmNTVlLTUyMzctNDA5ZC1hMTk2LTdhM2Q1ZTIwMTM0Mjwvc3RFdnQ6aW5zdGFuY2VJRD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmFjdGlvbj5zYXZlZDwvc3RFdnQ6YWN0aW9uPgogICAgICAgICAgICAgICA8L3JkZjpsaT4KICAgICAgICAgICAgICAgPHJkZjpsaSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpzb2Z0d2FyZUFnZW50PkFkb2JlIFBob3Rvc2hvcCBDYW1lcmEgUmF3IDguOCAoTWFjaW50b3NoKTwvc3RFdnQ6c29mdHdhcmVBZ2VudD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmNoYW5nZWQ+L21ldGFkYXRhPC9zdEV2dDpjaGFuZ2VkPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6d2hlbj4yMDE1LTA0LTIzVDIyOjMzOjM3LTA0OjAwPC9zdEV2dDp3aGVuPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6aW5zdGFuY2VJRD54bXAuaWlkOmUzNjExZWQ3LTI4YmYtNGE5MS1hZDA5LWVhNjc3M2U4Y2YyOTwvc3RFdnQ6aW5zdGFuY2VJRD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmFjdGlvbj5zYXZlZDwvc3RFdnQ6YWN0aW9uPgogICAgICAgICAgICAgICA8L3JkZjpsaT4KICAgICAgICAgICAgICAgPHJkZjpsaSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpzb2Z0d2FyZUFnZW50PkFkb2JlIFBob3Rvc2hvcCBDQyAoTWFjaW50b3NoKTwvc3RFdnQ6c29mdHdhcmVBZ2VudD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmNoYW5nZWQ+Lzwvc3RFdnQ6Y2hhbmdlZD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OndoZW4+MjAxNS0wNC0yOFQxMDowMTo1MS0wNDowMDwvc3RFdnQ6d2hlbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0Omluc3RhbmNlSUQ+eG1wLmlpZDo1MDViZDMzYS03ZDJiLTRiNzQtOTU1My0xNjIzYjE4MzExMmM8L3N0RXZ0Omluc3RhbmNlSUQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDphY3Rpb24+c2F2ZWQ8L3N0RXZ0OmFjdGlvbj4KICAgICAgICAgICAgICAgPC9yZGY6bGk+CiAgICAgICAgICAgICAgIDxyZGY6bGkgcmRmOnBhcnNlVHlwZT0iUmVzb3VyY2UiPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6c29mdHdhcmVBZ2VudD5BZG9iZSBQaG90b3Nob3AgQ1M2IChXaW5kb3dzKTwvc3RFdnQ6c29mdHdhcmVBZ2VudD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmNoYW5nZWQ+Lzwvc3RFdnQ6Y2hhbmdlZD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OndoZW4+MjAxNS0wNi0xOFQxMDowMjo1OS0wNDowMDwvc3RFdnQ6d2hlbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0Omluc3RhbmNlSUQ+eG1wLmlpZDpFMzBDRTVCOUMyMTVFNTExQkVDQkU3RTMxNDVCODA4NTwvc3RFdnQ6aW5zdGFuY2VJRD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmFjdGlvbj5zYXZlZDwvc3RFdnQ6YWN0aW9uPgogICAgICAgICAgICAgICA8L3JkZjpsaT4KICAgICAgICAgICAgICAgPHJkZjpsaSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpzb2Z0d2FyZUFnZW50PkFkb2JlIFBob3Rvc2hvcCBDYW1lcmEgUmF3IDguMjwvc3RFdnQ6c29mdHdhcmVBZ2VudD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmNoYW5nZWQ+L21ldGFkYXRhPC9zdEV2dDpjaGFuZ2VkPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6d2hlbj4yMDE1LTA2LTE4VDEwOjA0OjQ1LTA0OjAwPC9zdEV2dDp3aGVuPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6aW5zdGFuY2VJRD54bXAuaWlkOkE4MUY0NUYxQzIxNUU1MTE4OTE4RkI0OTg3NjBDNzI5PC9zdEV2dDppbnN0YW5jZUlEPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6YWN0aW9uPnNhdmVkPC9zdEV2dDphY3Rpb24+CiAgICAgICAgICAgICAgIDwvcmRmOmxpPgogICAgICAgICAgICAgICA8cmRmOmxpIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnNvZnR3YXJlQWdlbnQ+QWRvYmUgUGhvdG9zaG9wIENhbWVyYSBSYXcgOC4yIChXaW5kb3dzKTwvc3RFdnQ6c29mdHdhcmVBZ2VudD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmNoYW5nZWQ+L21ldGFkYXRhPC9zdEV2dDpjaGFuZ2VkPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6d2hlbj4yMDE1LTA2LTE4VDEwOjA1OjU1LTA0OjAwPC9zdEV2dDp3aGVuPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6aW5zdGFuY2VJRD54bXAuaWlkOjMzNTk0ZDkyLWNlMmYtNGE0Ny1iNTFmLTRmOTUzNjVmNWJkNTwvc3RFdnQ6aW5zdGFuY2VJRD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmFjdGlvbj5zYXZlZDwvc3RFdnQ6YWN0aW9uPgogICAgICAgICAgICAgICA8L3JkZjpsaT4KICAgICAgICAgICAgICAgPHJkZjpsaSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpzb2Z0d2FyZUFnZW50PkFkb2JlIFBob3Rvc2hvcCBDUzYgKFdpbmRvd3MpPC9zdEV2dDpzb2Z0d2FyZUFnZW50PgogICAgICAgICAgICAgICAgICA8c3RFdnQ6Y2hhbmdlZD4vPC9zdEV2dDpjaGFuZ2VkPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6d2hlbj4yMDE1LTA2LTE4VDExOjEyLTA0OjAwPC9zdEV2dDp3aGVuPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6aW5zdGFuY2VJRD54bXAuaWlkOjA3QUE3MDVFQ0MxNUU1MTE5NjEwQjRCN0U1NjM5OEUwPC9zdEV2dDppbnN0YW5jZUlEPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6YWN0aW9uPnNhdmVkPC9zdEV2dDphY3Rpb24+CiAgICAgICAgICAgICAgIDwvcmRmOmxpPgogICAgICAgICAgICAgICA8cmRmOmxpIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnNvZnR3YXJlQWdlbnQ+QWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cyk8L3N0RXZ0OnNvZnR3YXJlQWdlbnQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpjaGFuZ2VkPi88L3N0RXZ0OmNoYW5nZWQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDp3aGVuPjIwMTUtMDYtMThUMTE6MTM6NTMtMDQ6MDA8L3N0RXZ0OndoZW4+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDppbnN0YW5jZUlEPnhtcC5paWQ6MTFBQTcwNUVDQzE1RTUxMTk2MTBCNEI3RTU2Mzk4RTA8L3N0RXZ0Omluc3RhbmNlSUQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDphY3Rpb24+c2F2ZWQ8L3N0RXZ0OmFjdGlvbj4KICAgICAgICAgICAgICAgPC9yZGY6bGk+CiAgICAgICAgICAgIDwvcmRmOlNlcT4KICAgICAgICAgPC94bXBNTTpIaXN0b3J5PgogICAgICAgICA8eG1wTU06T3JpZ2luYWxEb2N1bWVudElEPnhtcC5kaWQ6RDY0OTMwOTYzODI3NjgxMTg3MUZEODQyOTcwMTYyOTc8L3htcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD4KICAgICAgICAgPHhtcE1NOkRlcml2ZWRGcm9tIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgPHN0UmVmOm9yaWdpbmFsRG9jdW1lbnRJRD54bXAuZGlkOkQ2NDkzMDk2MzgyNzY4MTE4NzFGRDg0Mjk3MDE2Mjk3PC9zdFJlZjpvcmlnaW5hbERvY3VtZW50SUQ+CiAgICAgICAgICAgIDxzdFJlZjppbnN0YW5jZUlEPnhtcC5paWQ6MDhGQ0MyNDVCMUU2RTQxMUI1QjBFN0EyNDU2MjFGRjY8L3N0UmVmOmluc3RhbmNlSUQ+CiAgICAgICAgICAgIDxzdFJlZjpkb2N1bWVudElEPnhtcC5kaWQ6RDY0OTMwOTYzODI3NjgxMTg3MUZEODQyOTcwMTYyOTc8L3N0UmVmOmRvY3VtZW50SUQ+CiAgICAgICAgIDwveG1wTU06RGVyaXZlZEZyb20+CiAgICAgICAg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';
diff --git a/packages/vertexai/__tests__/test-utils/cat.jpeg b/packages/vertexai/__tests__/test-utils/cat.jpeg
new file mode 100644
index 0000000000000000000000000000000000000000..2c21763bad2b0bf81dd3b4c2220e8595d5ee667f
GIT binary patch
literal 35160
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