From 95e7f0541bedf04f9f4dc2c9d3ec88898295afe0 Mon Sep 17 00:00:00 2001 From: Guillaume Bernos Date: Thu, 29 Sep 2022 15:24:06 +0200 Subject: [PATCH 01/13] feat(messaging): automatic export to bigquery --- .../FlutterFirebaseMessagingPlugin.java | 24 +++++++++++++++++++ .../method_channel_messaging.dart | 13 ++++++++++ .../platform_interface_messaging.dart | 7 ++++++ 3 files changed, 44 insertions(+) diff --git a/packages/firebase_messaging/firebase_messaging/android/src/main/java/io/flutter/plugins/firebase/messaging/FlutterFirebaseMessagingPlugin.java b/packages/firebase_messaging/firebase_messaging/android/src/main/java/io/flutter/plugins/firebase/messaging/FlutterFirebaseMessagingPlugin.java index c9ed2253c417..8ed355e61c50 100644 --- a/packages/firebase_messaging/firebase_messaging/android/src/main/java/io/flutter/plugins/firebase/messaging/FlutterFirebaseMessagingPlugin.java +++ b/packages/firebase_messaging/firebase_messaging/android/src/main/java/io/flutter/plugins/firebase/messaging/FlutterFirebaseMessagingPlugin.java @@ -251,6 +251,26 @@ private Task> setAutoInitEnabled(Map argumen return taskCompletionSource.getTask(); } + private Task setDeliveryMetricsExportToBigQuery(Map arguments) { + TaskCompletionSource taskCompletionSource = new TaskCompletionSource<>(); + + cachedThreadPool.execute( + () -> { + try { + FirebaseMessaging firebaseMessaging = + FlutterFirebaseMessagingUtils.getFirebaseMessagingForArguments(arguments); + Boolean enabled = (Boolean) Objects.requireNonNull(arguments.get("enabled")); + firebaseMessaging.setDeliveryMetricsExportToBigQuery(enabled); + taskCompletionSource.setResult(null); + } catch (Exception e) { + taskCompletionSource.setException(e); + } + }); + + return taskCompletionSource.getTask(); + } + + private Task> getInitialMessage() { TaskCompletionSource> taskCompletionSource = new TaskCompletionSource<>(); @@ -447,6 +467,9 @@ public void onMethodCall(final MethodCall call, @NonNull final Result result) { case "Messaging#setAutoInitEnabled": methodCallTask = setAutoInitEnabled(call.arguments()); break; + case "Messaging#setDeliveryMetricsExportToBigQuery": + methodCallTask = setDeliveryMetricsExportToBigQuery(call.arguments()); + break; case "Messaging#requestPermission": if (Build.VERSION.SDK_INT >= 33) { // Android version >= Android 13 requires user input if notification permission not set/granted @@ -478,6 +501,7 @@ public void onMethodCall(final MethodCall call, @NonNull final Result result) { }); } + private Map getExceptionDetails(@Nullable Exception exception) { Map details = new HashMap<>(); details.put("code", "unknown"); diff --git a/packages/firebase_messaging/firebase_messaging_platform_interface/lib/src/method_channel/method_channel_messaging.dart b/packages/firebase_messaging/firebase_messaging_platform_interface/lib/src/method_channel/method_channel_messaging.dart index 9c419a7bb699..878436598cb9 100644 --- a/packages/firebase_messaging/firebase_messaging_platform_interface/lib/src/method_channel/method_channel_messaging.dart +++ b/packages/firebase_messaging/firebase_messaging_platform_interface/lib/src/method_channel/method_channel_messaging.dart @@ -384,4 +384,17 @@ class MethodChannelFirebaseMessaging extends FirebaseMessagingPlatform { convertPlatformException(e, stack); } } + + @override + Future setDeliveryMetricsExportToBigQuery(bool enabled) async { + try { + await channel + .invokeMapMethod('Messaging#setDeliveryMetricsExportToBigQuery', { + 'appName': app.name, + 'enabled': enabled, + }); + } catch (e, stack) { + convertPlatformException(e, stack); + } + } } diff --git a/packages/firebase_messaging/firebase_messaging_platform_interface/lib/src/platform_interface/platform_interface_messaging.dart b/packages/firebase_messaging/firebase_messaging_platform_interface/lib/src/platform_interface/platform_interface_messaging.dart index c0b46b7a6bc3..c09f12a674f2 100644 --- a/packages/firebase_messaging/firebase_messaging_platform_interface/lib/src/platform_interface/platform_interface_messaging.dart +++ b/packages/firebase_messaging/firebase_messaging_platform_interface/lib/src/platform_interface/platform_interface_messaging.dart @@ -305,4 +305,11 @@ abstract class FirebaseMessagingPlatform extends PlatformInterface { Future unsubscribeFromTopic(String topic) { throw UnimplementedError('unsubscribeFromTopic() is not implemented'); } + + /// Enables or disables Firebase Cloud Messaging message delivery metrics export to BigQuery. + Future setDeliveryMetricsExportToBigQuery(bool enabled) { + throw UnimplementedError( + 'setDeliveryMetricsExportToBigQuery() is not implemented', + ); + } } From 5e5a8563d7c9f2832371d234d2db5ee52ba40507 Mon Sep 17 00:00:00 2001 From: Guillaume Bernos Date: Fri, 30 Sep 2022 10:35:47 +0200 Subject: [PATCH 02/13] feat(messaging): automatic export to bigquery for web --- .../lib/firebase_messaging_web.dart | 15 +++++++++++++++ .../lib/src/interop/messaging.dart | 16 +++++++++++++++- .../lib/src/interop/messaging_interop.dart | 7 ++++++- 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/packages/firebase_messaging/firebase_messaging_web/lib/firebase_messaging_web.dart b/packages/firebase_messaging/firebase_messaging_web/lib/firebase_messaging_web.dart index c9e607d74929..142d703e3921 100644 --- a/packages/firebase_messaging/firebase_messaging_web/lib/firebase_messaging_web.dart +++ b/packages/firebase_messaging/firebase_messaging_web/lib/firebase_messaging_web.dart @@ -118,6 +118,21 @@ class FirebaseMessagingWeb extends FirebaseMessagingPlatform { ); } + @override + Future setDeliveryMetricsExportToBigQuery(bool enabled) async { + _delegate; + + if (!_initialized) { + // no-op for unsupported browsers + return; + } + + return convertWebExceptions( + () => _delegate + .experimentalSetDeliveryMetricsExportedToBigQueryEnabled(enabled), + ); + } + @override Stream get onTokenRefresh { // onTokenRefresh is deprecated on web, however since this is a non-critical diff --git a/packages/firebase_messaging/firebase_messaging_web/lib/src/interop/messaging.dart b/packages/firebase_messaging/firebase_messaging_web/lib/src/interop/messaging.dart index 0a9a2fc5e7f6..8df16b352bba 100644 --- a/packages/firebase_messaging/firebase_messaging_web/lib/src/interop/messaging.dart +++ b/packages/firebase_messaging/firebase_messaging_web/lib/src/interop/messaging.dart @@ -7,9 +7,9 @@ import 'dart:async'; +import 'package:firebase_core_web/firebase_core_web_interop.dart'; import 'package:js/js.dart'; -import 'package:firebase_core_web/firebase_core_web_interop.dart'; import 'messaging_interop.dart' as messaging_interop; export 'messaging_interop.dart'; @@ -48,6 +48,20 @@ class Messaging extends JsObjectWrapper { ? null : messaging_interop.GetTokenOptions(vapidKey: vapidKey))); + /// Enables or disables Firebase Cloud Messaging message delivery metrics export to BigQuery. + /// By default, message delivery metrics are not exported to BigQuery. + /// Use this method to enable or disable the export at runtime. + Future experimentalSetDeliveryMetricsExportedToBigQueryEnabled( + bool enabled, + ) => + handleThenable( + messaging_interop + .experimentalSetDeliveryMetricsExportedToBigQueryEnabled( + jsObject, + enabled, + ), + ); + // ignore: close_sinks StreamController? _onMessageController; diff --git a/packages/firebase_messaging/firebase_messaging_web/lib/src/interop/messaging_interop.dart b/packages/firebase_messaging/firebase_messaging_web/lib/src/interop/messaging_interop.dart index 8083e77c0ac3..d2848c63650c 100644 --- a/packages/firebase_messaging/firebase_messaging_web/lib/src/interop/messaging_interop.dart +++ b/packages/firebase_messaging/firebase_messaging_web/lib/src/interop/messaging_interop.dart @@ -8,8 +8,8 @@ @JS('firebase_messaging') library firebase_interop.messaging; -import 'package:js/js.dart'; import 'package:firebase_core_web/firebase_core_web_interop.dart'; +import 'package:js/js.dart'; @JS() external MessagingJsImpl getMessaging([AppJsImpl? app]); @@ -21,6 +21,11 @@ external PromiseJsImpl deleteToken(MessagingJsImpl messaging); external PromiseJsImpl getToken( MessagingJsImpl messaging, GetTokenOptions? getTokenOptions); +@JS() +external PromiseJsImpl + experimentalSetDeliveryMetricsExportedToBigQueryEnabled( + MessagingJsImpl messaging, bool enabled); + @JS('isSupported') external PromiseJsImpl isSupported(); From b7e56b346cb79a2c8d46783d217182826bb27da9 Mon Sep 17 00:00:00 2001 From: Guillaume Bernos Date: Tue, 4 Oct 2022 09:44:13 +0200 Subject: [PATCH 03/13] feat(messaging): export to BigQuery --- .../firebase_messaging/lib/src/messaging.dart | 7 +++++++ .../method_channel/method_channel_messaging.dart | 4 ++++ .../firebase_messaging/firebase_messaging_e2e.dart | 13 +++++++++++-- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/packages/firebase_messaging/firebase_messaging/lib/src/messaging.dart b/packages/firebase_messaging/firebase_messaging/lib/src/messaging.dart index 8cd3e5a6a821..049faf763a8b 100644 --- a/packages/firebase_messaging/firebase_messaging/lib/src/messaging.dart +++ b/packages/firebase_messaging/firebase_messaging/lib/src/messaging.dart @@ -229,6 +229,13 @@ class FirebaseMessaging extends FirebasePluginPlatform { return _delegate.setAutoInitEnabled(enabled); } + /// Enables or disables Firebase Cloud Messaging message delivery metrics export to BigQuery. + /// + /// On iOS, you need to follow [this guide](https://firebase.google.com/docs/cloud-messaging/understand-delivery?platform=ios#enable_delivery_data_export_for_background_notifications) in order to export metrics to BigQuery. + Future setDeliveryMetricsExportToBigQuery(bool enabled) async { + return _delegate.setDeliveryMetricsExportToBigQuery(enabled); + } + /// Sets the presentation options for Apple notifications when received in /// the foreground. /// diff --git a/packages/firebase_messaging/firebase_messaging_platform_interface/lib/src/method_channel/method_channel_messaging.dart b/packages/firebase_messaging/firebase_messaging_platform_interface/lib/src/method_channel/method_channel_messaging.dart index 878436598cb9..c963088e911a 100644 --- a/packages/firebase_messaging/firebase_messaging_platform_interface/lib/src/method_channel/method_channel_messaging.dart +++ b/packages/firebase_messaging/firebase_messaging_platform_interface/lib/src/method_channel/method_channel_messaging.dart @@ -387,6 +387,10 @@ class MethodChannelFirebaseMessaging extends FirebaseMessagingPlatform { @override Future setDeliveryMetricsExportToBigQuery(bool enabled) async { + // The method is not available on iOS. + if (defaultTargetPlatform != TargetPlatform.android) { + return; + } try { await channel .invokeMapMethod('Messaging#setDeliveryMetricsExportToBigQuery', { diff --git a/tests/test_driver/firebase_messaging/firebase_messaging_e2e.dart b/tests/test_driver/firebase_messaging/firebase_messaging_e2e.dart index 3e72118869e9..85970aa112aa 100644 --- a/tests/test_driver/firebase_messaging/firebase_messaging_e2e.dart +++ b/tests/test_driver/firebase_messaging/firebase_messaging_e2e.dart @@ -4,11 +4,11 @@ import 'dart:async'; +import 'package:drive/drive.dart'; import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; - -import 'package:drive/drive.dart'; import 'package:flutter/foundation.dart'; + import '../firebase_default_options.dart'; // ignore: do_not_use_environment @@ -211,6 +211,15 @@ void setupTests() { skip: kIsWeb || defaultTargetPlatform == TargetPlatform.macOS, ); }); + + group('setDeliveryMetricsExportToBigQuery()', () { + test( + 'successfully subscribes from topic', + () async { + await messaging.setDeliveryMetricsExportToBigQuery(true); + }, + ); + }); }, ); } From 62350aafe109051f465564278b4fff1ce0638ba8 Mon Sep 17 00:00:00 2001 From: Guillaume Bernos Date: Tue, 4 Oct 2022 10:02:56 +0200 Subject: [PATCH 04/13] feat(messaging): export to BigQuery --- docs/cloud-messaging/receive.md | 45 +++++++++++++++++++ .../FlutterFirebaseMessagingPlugin.java | 24 +++++----- .../ios/Flutter/AppFrameworkInfo.plist | 2 +- .../firebase_messaging_e2e.dart | 3 +- 4 files changed, 59 insertions(+), 15 deletions(-) diff --git a/docs/cloud-messaging/receive.md b/docs/cloud-messaging/receive.md index 437d3e7290cc..027451a5638f 100644 --- a/docs/cloud-messaging/receive.md +++ b/docs/cloud-messaging/receive.md @@ -339,3 +339,48 @@ Here's how to use the second method: }, } ``` + + +## Enable message delivery data export + +You can export your message data into BigQuery for further analysis. BigQuery allows you to analyze the data using BigQuery SQL, +export it to another cloud provider, or use the data for your custom ML models. An export to BigQuery +includes all available data for messages, regardless of message type or whether the message is sent via +the API or the Notifications composer. + +To enable the export, first follow the steps [described here](https://firebase.google.com/docs/cloud-messaging/understand-delivery?platform=ios#bigquery-data-export), +then follow these instructions: + +### Android and Web + +You can use the following code: +```dart +await FirebaseMessaging.instance.setDeliveryMetricsExportToBigQuery(true); +``` + +### iOS + +For iOS, you need to change the `AppDelegate.m` with the following content. + +```objective-c +#import "AppDelegate.h" +#import "GeneratedPluginRegistrant.h" +#import + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + [GeneratedPluginRegistrant registerWithRegistry:self]; + // Override point for customization after application launch. + return [super application:application didFinishLaunchingWithOptions:launchOptions]; +} + +- (void)application:(UIApplication *)application + didReceiveRemoteNotification:(NSDictionary *)userInfo + fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { + [[FIRMessaging extensionHelper] exportDeliveryMetricsToBigQueryWithMessageInfo:userInfo]; +} + +@end +``` \ No newline at end of file diff --git a/packages/firebase_messaging/firebase_messaging/android/src/main/java/io/flutter/plugins/firebase/messaging/FlutterFirebaseMessagingPlugin.java b/packages/firebase_messaging/firebase_messaging/android/src/main/java/io/flutter/plugins/firebase/messaging/FlutterFirebaseMessagingPlugin.java index 8ed355e61c50..d6945069c76b 100644 --- a/packages/firebase_messaging/firebase_messaging/android/src/main/java/io/flutter/plugins/firebase/messaging/FlutterFirebaseMessagingPlugin.java +++ b/packages/firebase_messaging/firebase_messaging/android/src/main/java/io/flutter/plugins/firebase/messaging/FlutterFirebaseMessagingPlugin.java @@ -255,22 +255,21 @@ private Task setDeliveryMetricsExportToBigQuery(Map argume TaskCompletionSource taskCompletionSource = new TaskCompletionSource<>(); cachedThreadPool.execute( - () -> { - try { - FirebaseMessaging firebaseMessaging = - FlutterFirebaseMessagingUtils.getFirebaseMessagingForArguments(arguments); - Boolean enabled = (Boolean) Objects.requireNonNull(arguments.get("enabled")); - firebaseMessaging.setDeliveryMetricsExportToBigQuery(enabled); - taskCompletionSource.setResult(null); - } catch (Exception e) { - taskCompletionSource.setException(e); - } - }); + () -> { + try { + FirebaseMessaging firebaseMessaging = + FlutterFirebaseMessagingUtils.getFirebaseMessagingForArguments(arguments); + Boolean enabled = (Boolean) Objects.requireNonNull(arguments.get("enabled")); + firebaseMessaging.setDeliveryMetricsExportToBigQuery(enabled); + taskCompletionSource.setResult(null); + } catch (Exception e) { + taskCompletionSource.setException(e); + } + }); return taskCompletionSource.getTask(); } - private Task> getInitialMessage() { TaskCompletionSource> taskCompletionSource = new TaskCompletionSource<>(); @@ -501,7 +500,6 @@ public void onMethodCall(final MethodCall call, @NonNull final Result result) { }); } - private Map getExceptionDetails(@Nullable Exception exception) { Map details = new HashMap<>(); details.put("code", "unknown"); diff --git a/packages/firebase_messaging/firebase_messaging/example/ios/Flutter/AppFrameworkInfo.plist b/packages/firebase_messaging/firebase_messaging/example/ios/Flutter/AppFrameworkInfo.plist index f2872cf474ee..4f8d4d2456f3 100644 --- a/packages/firebase_messaging/firebase_messaging/example/ios/Flutter/AppFrameworkInfo.plist +++ b/packages/firebase_messaging/firebase_messaging/example/ios/Flutter/AppFrameworkInfo.plist @@ -21,6 +21,6 @@ CFBundleVersion 1.0 MinimumOSVersion - 9.0 + 11.0 diff --git a/tests/test_driver/firebase_messaging/firebase_messaging_e2e.dart b/tests/test_driver/firebase_messaging/firebase_messaging_e2e.dart index 85970aa112aa..89b8b88de9db 100644 --- a/tests/test_driver/firebase_messaging/firebase_messaging_e2e.dart +++ b/tests/test_driver/firebase_messaging/firebase_messaging_e2e.dart @@ -216,7 +216,8 @@ void setupTests() { test( 'successfully subscribes from topic', () async { - await messaging.setDeliveryMetricsExportToBigQuery(true); + await FirebaseMessaging.instance + .setDeliveryMetricsExportToBigQuery(true); }, ); }); From 1ae82d65b1193ec1f34f02b80c004a9040cd0443 Mon Sep 17 00:00:00 2001 From: Guillaume Bernos Date: Tue, 4 Oct 2022 10:47:00 +0200 Subject: [PATCH 05/13] feat(messaging): export to BigQuery --- .../firebase_messaging/firebase_messaging_e2e.dart | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/test_driver/firebase_messaging/firebase_messaging_e2e.dart b/tests/test_driver/firebase_messaging/firebase_messaging_e2e.dart index 89b8b88de9db..7ee6300d52aa 100644 --- a/tests/test_driver/firebase_messaging/firebase_messaging_e2e.dart +++ b/tests/test_driver/firebase_messaging/firebase_messaging_e2e.dart @@ -214,10 +214,9 @@ void setupTests() { group('setDeliveryMetricsExportToBigQuery()', () { test( - 'successfully subscribes from topic', + 'successfully set delivery metrics export to big query', () async { - await FirebaseMessaging.instance - .setDeliveryMetricsExportToBigQuery(true); + await messaging.setDeliveryMetricsExportToBigQuery(true); }, ); }); From c93e1ec5fb5c66624a06c864b44c0d9de780e49b Mon Sep 17 00:00:00 2001 From: Guillaume Bernos Date: Wed, 5 Oct 2022 09:14:31 +0200 Subject: [PATCH 06/13] feat(messaging): export to BigQuery on web --- .../firebase_messaging/example/.gitignore | 1 - .../firebase-messaging-sw.ts | 45 + .../bundled-service-worker/package.json | 11 + .../example/bundled-service-worker/yarn.lock | 1041 +++++++++++++++++ .../example/web/firebase-messaging-sw.js | 115 +- .../example/web/firebase-messaging-sw.js.map | 7 + .../firebase_messaging/example/web/index.html | 94 +- .../firebase_messaging/lib/src/messaging.dart | 6 +- .../lib/firebase_messaging_web.dart | 15 - .../lib/src/interop/messaging.dart | 14 - .../lib/src/interop/messaging_interop.dart | 5 - 11 files changed, 1251 insertions(+), 103 deletions(-) create mode 100644 packages/firebase_messaging/firebase_messaging/example/bundled-service-worker/firebase-messaging-sw.ts create mode 100644 packages/firebase_messaging/firebase_messaging/example/bundled-service-worker/package.json create mode 100644 packages/firebase_messaging/firebase_messaging/example/bundled-service-worker/yarn.lock create mode 100644 packages/firebase_messaging/firebase_messaging/example/web/firebase-messaging-sw.js.map diff --git a/packages/firebase_messaging/firebase_messaging/example/.gitignore b/packages/firebase_messaging/firebase_messaging/example/.gitignore index 9d532b18a01f..7283898501e8 100644 --- a/packages/firebase_messaging/firebase_messaging/example/.gitignore +++ b/packages/firebase_messaging/firebase_messaging/example/.gitignore @@ -32,7 +32,6 @@ /build/ # Web related -lib/generated_plugin_registrant.dart # Symbolication related app.*.symbols diff --git a/packages/firebase_messaging/firebase_messaging/example/bundled-service-worker/firebase-messaging-sw.ts b/packages/firebase_messaging/firebase_messaging/example/bundled-service-worker/firebase-messaging-sw.ts new file mode 100644 index 000000000000..b8e37e594ecb --- /dev/null +++ b/packages/firebase_messaging/firebase_messaging/example/bundled-service-worker/firebase-messaging-sw.ts @@ -0,0 +1,45 @@ +import { initializeApp } from 'firebase/app'; +import { + experimentalSetDeliveryMetricsExportedToBigQueryEnabled, + getMessaging, + isSupported, + onBackgroundMessage, +} from 'firebase/messaging/sw'; + +self.addEventListener('install', (event) => { + console.log(self); + console.log(event); +}); + +const app = initializeApp({ + apiKey: 'AIzaSyAgUhHU8wSJgO5MVNy95tMT07NEjzMOfz0', + authDomain: 'react-native-firebase-testing.firebaseapp.com', + databaseURL: 'https://react-native-firebase-testing.firebaseio.com', + projectId: 'react-native-firebase-testing', + storageBucket: 'react-native-firebase-testing.appspot.com', + messagingSenderId: '448618578101', + appId: '1:448618578101:web:ecaffe2bc4511738', +}); + +isSupported().then((isSupported) => { + if (isSupported) { + const messaging = getMessaging(app); + + experimentalSetDeliveryMetricsExportedToBigQueryEnabled(messaging, true); + + console.log('experimental working'); + + onBackgroundMessage(messaging, ({ notification: notification }) => { + const { title, body, image } = notification ?? {}; + + if (!title) { + return; + } + + self.registration.showNotification(title, { + body, + icon: image || '/assets/icons/icon-72x72.png', + }); + }); + } +}); diff --git a/packages/firebase_messaging/firebase_messaging/example/bundled-service-worker/package.json b/packages/firebase_messaging/firebase_messaging/example/bundled-service-worker/package.json new file mode 100644 index 000000000000..4aff08c96b71 --- /dev/null +++ b/packages/firebase_messaging/firebase_messaging/example/bundled-service-worker/package.json @@ -0,0 +1,11 @@ +{ + "dependencies": { + "firebase": "9" + }, + "devDependencies": { + "esbuild": "^0.15.10" + }, + "scripts": { + "build": "esbuild firebase-messaging-sw.ts --outdir=../web --bundle --sourcemap --minify --format=esm" + } +} diff --git a/packages/firebase_messaging/firebase_messaging/example/bundled-service-worker/yarn.lock b/packages/firebase_messaging/firebase_messaging/example/bundled-service-worker/yarn.lock new file mode 100644 index 000000000000..fb56528d2d31 --- /dev/null +++ b/packages/firebase_messaging/firebase_messaging/example/bundled-service-worker/yarn.lock @@ -0,0 +1,1041 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@esbuild/android-arm@0.15.10": + version "0.15.10" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.15.10.tgz#a5f9432eb221afc243c321058ef25fe899886892" + integrity sha512-FNONeQPy/ox+5NBkcSbYJxoXj9GWu8gVGJTVmUyoOCKQFDTrHVKgNSzChdNt0I8Aj/iKcsDf2r9BFwv+FSNUXg== + +"@esbuild/linux-loong64@0.15.10": + version "0.15.10" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.15.10.tgz#78a42897c2cf8db9fd5f1811f7590393b77774c7" + integrity sha512-w0Ou3Z83LOYEkwaui2M8VwIp+nLi/NA60lBLMvaJ+vXVMcsARYdEzLNE7RSm4+lSg4zq4d7fAVuzk7PNQ5JFgg== + +"@firebase/analytics-compat@0.1.13": + version "0.1.13" + resolved "https://registry.yarnpkg.com/@firebase/analytics-compat/-/analytics-compat-0.1.13.tgz#61e1d6f9e4d033c3ed9943d91530eb3e0f382f92" + integrity sha512-QC1DH/Dwc8fBihn0H+jocBWyE17GF1fOCpCrpAiQ2u16F/NqsVDVG4LjIqdhq963DXaXneNY7oDwa25Up682AA== + dependencies: + "@firebase/analytics" "0.8.0" + "@firebase/analytics-types" "0.7.0" + "@firebase/component" "0.5.17" + "@firebase/util" "1.6.3" + tslib "^2.1.0" + +"@firebase/analytics-types@0.7.0": + version "0.7.0" + resolved "https://registry.yarnpkg.com/@firebase/analytics-types/-/analytics-types-0.7.0.tgz#91960e7c87ce8bf18cf8dd9e55ccbf5dc3989b5d" + integrity sha512-DNE2Waiwy5+zZnCfintkDtBfaW6MjIG883474v6Z0K1XZIvl76cLND4iv0YUb48leyF+PJK1KO2XrgHb/KpmhQ== + +"@firebase/analytics@0.8.0": + version "0.8.0" + resolved "https://registry.yarnpkg.com/@firebase/analytics/-/analytics-0.8.0.tgz#b5d595082f57d33842b1fd9025d88f83065e87fe" + integrity sha512-wkcwainNm8Cu2xkJpDSHfhBSdDJn86Q1TZNmLWc67VrhZUHXIKXxIqb65/tNUVE+I8+sFiDDNwA+9R3MqTQTaA== + dependencies: + "@firebase/component" "0.5.17" + "@firebase/installations" "0.5.12" + "@firebase/logger" "0.3.3" + "@firebase/util" "1.6.3" + tslib "^2.1.0" + +"@firebase/app-check-compat@0.2.12": + version "0.2.12" + resolved "https://registry.yarnpkg.com/@firebase/app-check-compat/-/app-check-compat-0.2.12.tgz#e30b2395e3d30f8cfcf3554fc87875f82c1aa086" + integrity sha512-GFppNLlUyMN9Iq31ME/+GkjRVKlc+MeanzUKQ9UaR73ZsYH3oX3Ja+xjoYgixaVJDDG+ofBYR7ZXTkkQdSR/pw== + dependencies: + "@firebase/app-check" "0.5.12" + "@firebase/app-check-types" "0.4.0" + "@firebase/component" "0.5.17" + "@firebase/logger" "0.3.3" + "@firebase/util" "1.6.3" + tslib "^2.1.0" + +"@firebase/app-check-interop-types@0.1.0": + version "0.1.0" + resolved "https://registry.yarnpkg.com/@firebase/app-check-interop-types/-/app-check-interop-types-0.1.0.tgz#83afd9d41f99166c2bdb2d824e5032e9edd8fe53" + integrity sha512-uZfn9s4uuRsaX5Lwx+gFP3B6YsyOKUE+Rqa6z9ojT4VSRAsZFko9FRn6OxQUA1z5t5d08fY4pf+/+Dkd5wbdbA== + +"@firebase/app-check-types@0.4.0": + version "0.4.0" + resolved "https://registry.yarnpkg.com/@firebase/app-check-types/-/app-check-types-0.4.0.tgz#7007a9d1d720db20bcf466fe6785c96feaa0a82d" + integrity sha512-SsWafqMABIOu7zLgWbmwvHGOeQQVQlwm42kwwubsmfLmL4Sf5uGpBfDhQ0CAkpi7bkJ/NwNFKafNDL9prRNP0Q== + +"@firebase/app-check@0.5.12": + version "0.5.12" + resolved "https://registry.yarnpkg.com/@firebase/app-check/-/app-check-0.5.12.tgz#82f305cc01bfe4d32c35e425941b2eca2ce9f089" + integrity sha512-l+MmvupSGT/F+I5ei7XjhEfpoL4hLVJr0vUwcG5NEf2hAkQnySli9fnbl9fZu1BJaQ2kthrMmtg1gcbcM9BUCQ== + dependencies: + "@firebase/component" "0.5.17" + "@firebase/logger" "0.3.3" + "@firebase/util" "1.6.3" + tslib "^2.1.0" + +"@firebase/app-compat@0.1.34": + version "0.1.34" + resolved "https://registry.yarnpkg.com/@firebase/app-compat/-/app-compat-0.1.34.tgz#a54fc94e464d3fabe502506a68ab563b53b14624" + integrity sha512-3XSrHDgtASIH8j6sDngiKykDcqlEM0mYplJTYdyN69ruZ1o0M+bUhIvX9mUoRelWZGT1BcMpFmh/62vz/wN72Q== + dependencies: + "@firebase/app" "0.7.33" + "@firebase/component" "0.5.17" + "@firebase/logger" "0.3.3" + "@firebase/util" "1.6.3" + tslib "^2.1.0" + +"@firebase/app-types@0.7.0": + version "0.7.0" + resolved "https://registry.yarnpkg.com/@firebase/app-types/-/app-types-0.7.0.tgz#c9e16d1b8bed1a991840b8d2a725fb58d0b5899f" + integrity sha512-6fbHQwDv2jp/v6bXhBw2eSRbNBpxHcd1NBF864UksSMVIqIyri9qpJB1Mn6sGZE+bnDsSQBC5j2TbMxYsJQkQg== + +"@firebase/app@0.7.33": + version "0.7.33" + resolved "https://registry.yarnpkg.com/@firebase/app/-/app-0.7.33.tgz#499c6febe8608d68090c4e3a5204004bb995f819" + integrity sha512-7K7ljuFhbT9uF0gTvuA7ZrpFFnS1eJLplfjJdjDQFWyjD6Cwk0FXNdu75WvoWgywoQCGiVBX8u5Jb437UQIhWQ== + dependencies: + "@firebase/component" "0.5.17" + "@firebase/logger" "0.3.3" + "@firebase/util" "1.6.3" + idb "7.0.1" + tslib "^2.1.0" + +"@firebase/auth-compat@0.2.20": + version "0.2.20" + resolved "https://registry.yarnpkg.com/@firebase/auth-compat/-/auth-compat-0.2.20.tgz#c5cd1c0abc5825c634adeaf5d767067c53a17c46" + integrity sha512-UwDxCQ2/+8dTp0oE6CmrR1n5e78H8By3hNBiTtwSqP/H2ZWxn9SfCdGt5PXF6NTnWAZ/0rs490RPM0koCYxkjA== + dependencies: + "@firebase/auth" "0.20.7" + "@firebase/auth-types" "0.11.0" + "@firebase/component" "0.5.17" + "@firebase/util" "1.6.3" + node-fetch "2.6.7" + selenium-webdriver "4.1.2" + tslib "^2.1.0" + +"@firebase/auth-interop-types@0.1.6": + version "0.1.6" + resolved "https://registry.yarnpkg.com/@firebase/auth-interop-types/-/auth-interop-types-0.1.6.tgz#5ce13fc1c527ad36f1bb1322c4492680a6cf4964" + integrity sha512-etIi92fW3CctsmR9e3sYM3Uqnoq861M0Id9mdOPF6PWIg38BXL5k4upCNBggGUpLIS0H1grMOvy/wn1xymwe2g== + +"@firebase/auth-types@0.11.0": + version "0.11.0" + resolved "https://registry.yarnpkg.com/@firebase/auth-types/-/auth-types-0.11.0.tgz#b9c73c60ca07945b3bbd7a097633e5f78fa9e886" + integrity sha512-q7Bt6cx+ySj9elQHTsKulwk3+qDezhzRBFC9zlQ1BjgMueUOnGMcvqmU0zuKlQ4RhLSH7MNAdBV2znVaoN3Vxw== + +"@firebase/auth@0.20.7": + version "0.20.7" + resolved "https://registry.yarnpkg.com/@firebase/auth/-/auth-0.20.7.tgz#50a79d3dfac802bc8383e8182057deda1595b62b" + integrity sha512-hKjnMZWOwn/HNSJNLAVmlBRQKRMOHGiD7vTMT2Og4oV8sFwRygxyoC7/OsupCUA6GuC4XsnDP/+WgE9LOcqB2A== + dependencies: + "@firebase/component" "0.5.17" + "@firebase/logger" "0.3.3" + "@firebase/util" "1.6.3" + node-fetch "2.6.7" + selenium-webdriver "4.1.2" + tslib "^2.1.0" + +"@firebase/component@0.5.17": + version "0.5.17" + resolved "https://registry.yarnpkg.com/@firebase/component/-/component-0.5.17.tgz#89291f378714df05d44430c524708669380d8ea6" + integrity sha512-mTM5CBSIlmI+i76qU4+DhuExnWtzcPS3cVgObA3VAjliPPr3GrUlTaaa8KBGfxsD27juQxMsYA0TvCR5X+GQ3Q== + dependencies: + "@firebase/util" "1.6.3" + tslib "^2.1.0" + +"@firebase/database-compat@0.2.6": + version "0.2.6" + resolved "https://registry.yarnpkg.com/@firebase/database-compat/-/database-compat-0.2.6.tgz#c8f3998f42ff00d01aad82e525e47aca6fe3d282" + integrity sha512-Ls1BAODaiDYgeJljrIgSuC7JkFIY/HNhhNYebzZSoGQU62RuvnaO3Qgp2EH6h2LzHyRnycNadfh1suROtPaUIA== + dependencies: + "@firebase/component" "0.5.17" + "@firebase/database" "0.13.6" + "@firebase/database-types" "0.9.13" + "@firebase/logger" "0.3.3" + "@firebase/util" "1.6.3" + tslib "^2.1.0" + +"@firebase/database-types@0.9.13": + version "0.9.13" + resolved "https://registry.yarnpkg.com/@firebase/database-types/-/database-types-0.9.13.tgz#47c12593ed27a9562f0919b7d3a1f1e00888abc2" + integrity sha512-dIJ1zGe3EHMhwcvukTOPzYlFYFIG1Et5Znl7s7y/ZTN2/toARRNnsv1qCKvqevIMYKvIrRsYOYfOXDS8l1YIJA== + dependencies: + "@firebase/app-types" "0.7.0" + "@firebase/util" "1.6.3" + +"@firebase/database@0.13.6": + version "0.13.6" + resolved "https://registry.yarnpkg.com/@firebase/database/-/database-0.13.6.tgz#fb2493d65759400ad155f156def068447ca1bfb1" + integrity sha512-5IZIBw2LT50Z8mwmKYmdX37p+Gg2HgeJsrruZmRyOSVgbfoY4Pg87n1uFx6qWqDmfL6HwQgwcrrQfVIXE3C5SA== + dependencies: + "@firebase/auth-interop-types" "0.1.6" + "@firebase/component" "0.5.17" + "@firebase/logger" "0.3.3" + "@firebase/util" "1.6.3" + faye-websocket "0.11.4" + tslib "^2.1.0" + +"@firebase/firestore-compat@0.1.25": + version "0.1.25" + resolved "https://registry.yarnpkg.com/@firebase/firestore-compat/-/firestore-compat-0.1.25.tgz#77ffdbc49d5734be60762a45c0f4d855772d1e46" + integrity sha512-Pf7Aa1dzG2/2bmC5kQmNo5U8RtnwGxEysuAJE9T7QrmEyi0RkzYFNp9sSfSIC7kWKhT/KfmGcDcQq4dtL9oFWQ== + dependencies: + "@firebase/component" "0.5.17" + "@firebase/firestore" "3.5.0" + "@firebase/firestore-types" "2.5.0" + "@firebase/util" "1.6.3" + tslib "^2.1.0" + +"@firebase/firestore-types@2.5.0": + version "2.5.0" + resolved "https://registry.yarnpkg.com/@firebase/firestore-types/-/firestore-types-2.5.0.tgz#16fca40b6980fdb000de86042d7a96635f2bcdd7" + integrity sha512-I6c2m1zUhZ5SH0cWPmINabDyH5w0PPFHk2UHsjBpKdZllzJZ2TwTkXbDtpHUZNmnc/zAa0WNMNMvcvbb/xJLKA== + +"@firebase/firestore@3.5.0": + version "3.5.0" + resolved "https://registry.yarnpkg.com/@firebase/firestore/-/firestore-3.5.0.tgz#8938fc8804cd150d154fde7a607a4461b079a62f" + integrity sha512-ZwpZROpHDAwX4dvthkYv5WTqzWMPDNIVFWifDYpelWclsRN0cBxqLZPzh2wBtOWwMLIOoau7QIltzapqLZaScw== + dependencies: + "@firebase/component" "0.5.17" + "@firebase/logger" "0.3.3" + "@firebase/util" "1.6.3" + "@firebase/webchannel-wrapper" "0.7.0" + "@grpc/grpc-js" "^1.3.2" + "@grpc/proto-loader" "^0.6.13" + node-fetch "2.6.7" + tslib "^2.1.0" + +"@firebase/functions-compat@0.2.4": + version "0.2.4" + resolved "https://registry.yarnpkg.com/@firebase/functions-compat/-/functions-compat-0.2.4.tgz#afa5d8eefe6d51c7b89e44d9262700b68fbcb73f" + integrity sha512-Crfn6il1yXGuXkjSd8nKrqR4XxPvuP19g64bXpM6Ix67qOkQg676kyOuww0FF17xN0NSXHfG8Pyf+CUrx8wJ5g== + dependencies: + "@firebase/component" "0.5.17" + "@firebase/functions" "0.8.4" + "@firebase/functions-types" "0.5.0" + "@firebase/util" "1.6.3" + tslib "^2.1.0" + +"@firebase/functions-types@0.5.0": + version "0.5.0" + resolved "https://registry.yarnpkg.com/@firebase/functions-types/-/functions-types-0.5.0.tgz#b50ba95ccce9e96f7cda453228ffe1684645625b" + integrity sha512-qza0M5EwX+Ocrl1cYI14zoipUX4gI/Shwqv0C1nB864INAD42Dgv4v94BCyxGHBg2kzlWy8PNafdP7zPO8aJQA== + +"@firebase/functions@0.8.4": + version "0.8.4" + resolved "https://registry.yarnpkg.com/@firebase/functions/-/functions-0.8.4.tgz#a9b7a10314f286df1ded87d8546fb8d9107a9c06" + integrity sha512-o1bB0xMyQKe+b246zGnjwHj4R6BH4mU2ZrSaa/3QvTpahUQ3hqYfkZPLOXCU7+vEFxHb3Hd4UUjkFhxoAcPqLA== + dependencies: + "@firebase/app-check-interop-types" "0.1.0" + "@firebase/auth-interop-types" "0.1.6" + "@firebase/component" "0.5.17" + "@firebase/messaging-interop-types" "0.1.0" + "@firebase/util" "1.6.3" + node-fetch "2.6.7" + tslib "^2.1.0" + +"@firebase/installations-compat@0.1.12": + version "0.1.12" + resolved "https://registry.yarnpkg.com/@firebase/installations-compat/-/installations-compat-0.1.12.tgz#d0394127f71aff596cb8bb607840095d1617246e" + integrity sha512-BIhFpWIn/GkuOa+jnXkp3SDJT2RLYJF6MWpinHIBKFJs7MfrgYZ3zQ1AlhobDEql+bkD1dK4dB5sNcET2T+EyA== + dependencies: + "@firebase/component" "0.5.17" + "@firebase/installations" "0.5.12" + "@firebase/installations-types" "0.4.0" + "@firebase/util" "1.6.3" + tslib "^2.1.0" + +"@firebase/installations-types@0.4.0": + version "0.4.0" + resolved "https://registry.yarnpkg.com/@firebase/installations-types/-/installations-types-0.4.0.tgz#256782ff9adfb390ac658c25bc32f89635ddce7c" + integrity sha512-nXxWKQDvBGctuvsizbUEJKfxXU9WAaDhon+j0jpjIfOJkvkj3YHqlLB/HeYjpUn85Pb22BjplpTnDn4Gm9pc3A== + +"@firebase/installations@0.5.12": + version "0.5.12" + resolved "https://registry.yarnpkg.com/@firebase/installations/-/installations-0.5.12.tgz#1d5764aa6f0b73d9d6d1a81a07eab5cd71a5ea27" + integrity sha512-Zq43fCE0PB5tGJ3ojzx5RNQzKdej1188qgAk22rwjuhP7npaG/PlJqDG1/V0ZjTLRePZ1xGrfXSPlA17c/vtNw== + dependencies: + "@firebase/component" "0.5.17" + "@firebase/util" "1.6.3" + idb "7.0.1" + tslib "^2.1.0" + +"@firebase/logger@0.3.3": + version "0.3.3" + resolved "https://registry.yarnpkg.com/@firebase/logger/-/logger-0.3.3.tgz#0f724b1e0b166d17ac285aac5c8ec14d136beed4" + integrity sha512-POTJl07jOKTOevLXrTvJD/VZ0M6PnJXflbAh5J9VGkmtXPXNG6MdZ9fmRgqYhXKTaDId6AQenQ262uwgpdtO0Q== + dependencies: + tslib "^2.1.0" + +"@firebase/messaging-compat@0.1.16": + version "0.1.16" + resolved "https://registry.yarnpkg.com/@firebase/messaging-compat/-/messaging-compat-0.1.16.tgz#4fe4e2c1b496e62f63e815cb242a2ab323cd7899" + integrity sha512-uG7rWcXJzU8vvlEBFpwG1ndw/GURrrmKcwsHopEWbsPGjMRaVWa7XrdKbvIR7IZohqPzcC/V9L8EeqF4Q4lz8w== + dependencies: + "@firebase/component" "0.5.17" + "@firebase/messaging" "0.9.16" + "@firebase/util" "1.6.3" + tslib "^2.1.0" + +"@firebase/messaging-interop-types@0.1.0": + version "0.1.0" + resolved "https://registry.yarnpkg.com/@firebase/messaging-interop-types/-/messaging-interop-types-0.1.0.tgz#bdac02dd31edd5cb9eec37b1db698ea5e2c1a631" + integrity sha512-DbvUl/rXAZpQeKBnwz0NYY5OCqr2nFA0Bj28Fmr3NXGqR4PAkfTOHuQlVtLO1Nudo3q0HxAYLa68ZDAcuv2uKQ== + +"@firebase/messaging@0.9.16": + version "0.9.16" + resolved "https://registry.yarnpkg.com/@firebase/messaging/-/messaging-0.9.16.tgz#96b57ebbb054e57f78585f85f59d521c5ba5cd85" + integrity sha512-Yl9gGrAvJF6C1gg3+Cr2HxlL6APsDEkrorkFafmSP1l+rg1epZKoOAcKJbSF02Vtb50wfb9FqGGy8tzodgETxg== + dependencies: + "@firebase/component" "0.5.17" + "@firebase/installations" "0.5.12" + "@firebase/messaging-interop-types" "0.1.0" + "@firebase/util" "1.6.3" + idb "7.0.1" + tslib "^2.1.0" + +"@firebase/performance-compat@0.1.12": + version "0.1.12" + resolved "https://registry.yarnpkg.com/@firebase/performance-compat/-/performance-compat-0.1.12.tgz#ac50b0cd29bf7f5e1e33c640dba25e2f8db95f0b" + integrity sha512-IBORzUeGY1MGdZnsix9Mu5z4+C3WHIwalu0usxvygL0EZKHztGG8bppYPGH/b5vvg8QyHs9U+Pn1Ot2jZhffQQ== + dependencies: + "@firebase/component" "0.5.17" + "@firebase/logger" "0.3.3" + "@firebase/performance" "0.5.12" + "@firebase/performance-types" "0.1.0" + "@firebase/util" "1.6.3" + tslib "^2.1.0" + +"@firebase/performance-types@0.1.0": + version "0.1.0" + resolved "https://registry.yarnpkg.com/@firebase/performance-types/-/performance-types-0.1.0.tgz#5e6efa9dc81860aee2cb7121b39ae8fa137e69fc" + integrity sha512-6p1HxrH0mpx+622Ql6fcxFxfkYSBpE3LSuwM7iTtYU2nw91Hj6THC8Bc8z4nboIq7WvgsT/kOTYVVZzCSlXl8w== + +"@firebase/performance@0.5.12": + version "0.5.12" + resolved "https://registry.yarnpkg.com/@firebase/performance/-/performance-0.5.12.tgz#4eae3eb91eeffb29b996e7908172052d4a901856" + integrity sha512-MPVTkOkGrm2SMQgI1FPNBm85y2pPqlPb6VDjIMCWkVpAr6G1IZzUT24yEMySRcIlK/Hh7/Qu1Nu5ASRzRuX6+Q== + dependencies: + "@firebase/component" "0.5.17" + "@firebase/installations" "0.5.12" + "@firebase/logger" "0.3.3" + "@firebase/util" "1.6.3" + tslib "^2.1.0" + +"@firebase/remote-config-compat@0.1.12": + version "0.1.12" + resolved "https://registry.yarnpkg.com/@firebase/remote-config-compat/-/remote-config-compat-0.1.12.tgz#7606752d7bfe2701d58568345ca536beda14ee53" + integrity sha512-Yz7Gtb2rLa7ykXZX9DnSTId8CXd++jFFLW3foUImrYwJEtWgLJc7gwkRfd1M73IlKGNuQAY+DpUNF0n1dLbecA== + dependencies: + "@firebase/component" "0.5.17" + "@firebase/logger" "0.3.3" + "@firebase/remote-config" "0.3.11" + "@firebase/remote-config-types" "0.2.0" + "@firebase/util" "1.6.3" + tslib "^2.1.0" + +"@firebase/remote-config-types@0.2.0": + version "0.2.0" + resolved "https://registry.yarnpkg.com/@firebase/remote-config-types/-/remote-config-types-0.2.0.tgz#1e2759fc01f20b58c564db42196f075844c3d1fd" + integrity sha512-hqK5sCPeZvcHQ1D6VjJZdW6EexLTXNMJfPdTwbD8NrXUw6UjWC4KWhLK/TSlL0QPsQtcKRkaaoP+9QCgKfMFPw== + +"@firebase/remote-config@0.3.11": + version "0.3.11" + resolved "https://registry.yarnpkg.com/@firebase/remote-config/-/remote-config-0.3.11.tgz#93c82b5944a20c027f4ee82c145813ca96b430bb" + integrity sha512-qA84dstrvVpO7rWT/sb2CLv1kjHVmz59SRFPKohJJYFBcPOGK4Pe4FWWhKAE9yg1Gnl0qYAGkahOwNawq3vE0g== + dependencies: + "@firebase/component" "0.5.17" + "@firebase/installations" "0.5.12" + "@firebase/logger" "0.3.3" + "@firebase/util" "1.6.3" + tslib "^2.1.0" + +"@firebase/storage-compat@0.1.17": + version "0.1.17" + resolved "https://registry.yarnpkg.com/@firebase/storage-compat/-/storage-compat-0.1.17.tgz#da721071e006d066fb9b1cff69481bd59a02346b" + integrity sha512-nOYmnpI0gwoz5nROseMi9WbmHGf+xumfsOvdPyMZAjy0VqbDnpKIwmTUZQBdR+bLuB5oIkHQsvw9nbb1SH+PzQ== + dependencies: + "@firebase/component" "0.5.17" + "@firebase/storage" "0.9.9" + "@firebase/storage-types" "0.6.0" + "@firebase/util" "1.6.3" + tslib "^2.1.0" + +"@firebase/storage-types@0.6.0": + version "0.6.0" + resolved "https://registry.yarnpkg.com/@firebase/storage-types/-/storage-types-0.6.0.tgz#0b1af64a2965af46fca138e5b70700e9b7e6312a" + integrity sha512-1LpWhcCb1ftpkP/akhzjzeFxgVefs6eMD2QeKiJJUGH1qOiows2w5o0sKCUSQrvrRQS1lz3SFGvNR1Ck/gqxeA== + +"@firebase/storage@0.9.9": + version "0.9.9" + resolved "https://registry.yarnpkg.com/@firebase/storage/-/storage-0.9.9.tgz#3d0080dd130bc3315731483384a7ef7c00f76e22" + integrity sha512-Zch7srLT2SIh9y2nCVv/4Kne0HULn7OPkmreY70BJTUJ+g5WLRjggBq6x9fV5ls9V38iqMWfn4prxzX8yIc08A== + dependencies: + "@firebase/component" "0.5.17" + "@firebase/util" "1.6.3" + node-fetch "2.6.7" + tslib "^2.1.0" + +"@firebase/util@1.6.3": + version "1.6.3" + resolved "https://registry.yarnpkg.com/@firebase/util/-/util-1.6.3.tgz#76128c1b5684c031823e95f6c08a7fb8560655c6" + integrity sha512-FujteO6Zjv6v8A4HS+t7c+PjU0Kaxj+rOnka0BsI/twUaCC9t8EQPmXpWZdk7XfszfahJn2pqsflUWUhtUkRlg== + dependencies: + tslib "^2.1.0" + +"@firebase/webchannel-wrapper@0.7.0": + version "0.7.0" + resolved "https://registry.yarnpkg.com/@firebase/webchannel-wrapper/-/webchannel-wrapper-0.7.0.tgz#a928358aac3aca652f417c402950d05a7a81d256" + integrity sha512-4ACd/c6ushrLuhn0+yjB9hznhnsc2IML6pf0Ulb1Q7w8SvR1jNGPu/Y7i4kvOm6R+WJkMHwyy5z3i3gN+Tawug== + +"@grpc/grpc-js@^1.3.2": + version "1.7.1" + resolved "https://registry.yarnpkg.com/@grpc/grpc-js/-/grpc-js-1.7.1.tgz#cfac092e61eac6fe0f80d22943f98e1ba45f02a2" + integrity sha512-GVtMU4oh/TeKkWGzXUEsyZtyvSUIT1z49RtGH1UnEGeL+sLuxKl8QH3KZTlSB329R1sWJmesm5hQ5CxXdYH9dg== + dependencies: + "@grpc/proto-loader" "^0.7.0" + "@types/node" ">=12.12.47" + +"@grpc/proto-loader@^0.6.13": + version "0.6.13" + resolved "https://registry.yarnpkg.com/@grpc/proto-loader/-/proto-loader-0.6.13.tgz#008f989b72a40c60c96cd4088522f09b05ac66bc" + integrity sha512-FjxPYDRTn6Ec3V0arm1FtSpmP6V50wuph2yILpyvTKzjc76oDdoihXqM1DzOW5ubvCC8GivfCnNtfaRE8myJ7g== + dependencies: + "@types/long" "^4.0.1" + lodash.camelcase "^4.3.0" + long "^4.0.0" + protobufjs "^6.11.3" + yargs "^16.2.0" + +"@grpc/proto-loader@^0.7.0": + version "0.7.3" + resolved "https://registry.yarnpkg.com/@grpc/proto-loader/-/proto-loader-0.7.3.tgz#75a6f95b51b85c5078ac7394da93850c32d36bb8" + integrity sha512-5dAvoZwna2Py3Ef96Ux9jIkp3iZ62TUsV00p3wVBPNX5K178UbNi8Q7gQVqwXT1Yq9RejIGG9G2IPEo93T6RcA== + dependencies: + "@types/long" "^4.0.1" + lodash.camelcase "^4.3.0" + long "^4.0.0" + protobufjs "^7.0.0" + yargs "^16.2.0" + +"@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" + integrity sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ== + +"@protobufjs/base64@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/base64/-/base64-1.1.2.tgz#4c85730e59b9a1f1f349047dbf24296034bb2735" + integrity sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg== + +"@protobufjs/codegen@^2.0.4": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@protobufjs/codegen/-/codegen-2.0.4.tgz#7ef37f0d010fb028ad1ad59722e506d9262815cb" + integrity sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg== + +"@protobufjs/eventemitter@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70" + integrity sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q== + +"@protobufjs/fetch@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45" + integrity sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ== + dependencies: + "@protobufjs/aspromise" "^1.1.1" + "@protobufjs/inquire" "^1.1.0" + +"@protobufjs/float@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1" + integrity sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ== + +"@protobufjs/inquire@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089" + integrity sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q== + +"@protobufjs/path@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d" + integrity sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA== + +"@protobufjs/pool@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54" + integrity sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw== + +"@protobufjs/utf8@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" + integrity sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw== + +"@types/long@^4.0.1": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.2.tgz#b74129719fc8d11c01868010082d483b7545591a" + integrity sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA== + +"@types/node@>=12.12.47", "@types/node@>=13.7.0": + version "18.8.2" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.8.2.tgz#17d42c6322d917764dd3d2d3a10d7884925de067" + integrity sha512-cRMwIgdDN43GO4xMWAfJAecYn8wV4JbsOGHNfNUIDiuYkUYAR5ec4Rj7IO2SAhFPEfpPtLtUTbbny/TCT7aDwA== + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-styles@^4.0.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +cliui@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" + integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^7.0.0" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +core-util-is@~1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" + integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +esbuild-android-64@0.15.10: + version "0.15.10" + resolved "https://registry.yarnpkg.com/esbuild-android-64/-/esbuild-android-64-0.15.10.tgz#8a59a84acbf2eca96996cadc35642cf055c494f0" + integrity sha512-UI7krF8OYO1N7JYTgLT9ML5j4+45ra3amLZKx7LO3lmLt1Ibn8t3aZbX5Pu4BjWiqDuJ3m/hsvhPhK/5Y/YpnA== + +esbuild-android-arm64@0.15.10: + version "0.15.10" + resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.15.10.tgz#f453851dc1d8c5409a38cf7613a33852faf4915d" + integrity sha512-EOt55D6xBk5O05AK8brXUbZmoFj4chM8u3riGflLa6ziEoVvNjRdD7Cnp82NHQGfSHgYR06XsPI8/sMuA/cUwg== + +esbuild-darwin-64@0.15.10: + version "0.15.10" + resolved "https://registry.yarnpkg.com/esbuild-darwin-64/-/esbuild-darwin-64-0.15.10.tgz#778bd29c8186ff47b176c8af58c08cf0fb8e6b86" + integrity sha512-hbDJugTicqIm+WKZgp208d7FcXcaK8j2c0l+fqSJ3d2AzQAfjEYDRM3Z2oMeqSJ9uFxyj/muSACLdix7oTstRA== + +esbuild-darwin-arm64@0.15.10: + version "0.15.10" + resolved "https://registry.yarnpkg.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.10.tgz#b30bbefb46dc3c5d4708b0435e52f6456578d6df" + integrity sha512-M1t5+Kj4IgSbYmunf2BB6EKLkWUq+XlqaFRiGOk8bmBapu9bCDrxjf4kUnWn59Dka3I27EiuHBKd1rSO4osLFQ== + +esbuild-freebsd-64@0.15.10: + version "0.15.10" + resolved "https://registry.yarnpkg.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.10.tgz#ab301c5f6ded5110dbdd611140bef1a7c2e99236" + integrity sha512-KMBFMa7C8oc97nqDdoZwtDBX7gfpolkk6Bcmj6YFMrtCMVgoU/x2DI1p74DmYl7CSS6Ppa3xgemrLrr5IjIn0w== + +esbuild-freebsd-arm64@0.15.10: + version "0.15.10" + resolved "https://registry.yarnpkg.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.10.tgz#a5b09b867a6ff49110f52343b6f12265db63d43f" + integrity sha512-m2KNbuCX13yQqLlbSojFMHpewbn8wW5uDS6DxRpmaZKzyq8Dbsku6hHvh2U+BcLwWY4mpgXzFUoENEf7IcioGg== + +esbuild-linux-32@0.15.10: + version "0.15.10" + resolved "https://registry.yarnpkg.com/esbuild-linux-32/-/esbuild-linux-32-0.15.10.tgz#5282fe9915641caf9c8070e4ba2c3e16d358f837" + integrity sha512-guXrwSYFAvNkuQ39FNeV4sNkNms1bLlA5vF1H0cazZBOLdLFIny6BhT+TUbK/hdByMQhtWQ5jI9VAmPKbVPu1w== + +esbuild-linux-64@0.15.10: + version "0.15.10" + resolved "https://registry.yarnpkg.com/esbuild-linux-64/-/esbuild-linux-64-0.15.10.tgz#f3726e85a00149580cb19f8abfabcbb96f5d52bb" + integrity sha512-jd8XfaSJeucMpD63YNMO1JCrdJhckHWcMv6O233bL4l6ogQKQOxBYSRP/XLWP+6kVTu0obXovuckJDcA0DKtQA== + +esbuild-linux-arm64@0.15.10: + version "0.15.10" + resolved "https://registry.yarnpkg.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.10.tgz#2f0056e9d5286edb0185b56655caa8c574d8dbe7" + integrity sha512-GByBi4fgkvZFTHFDYNftu1DQ1GzR23jws0oWyCfhnI7eMOe+wgwWrc78dbNk709Ivdr/evefm2PJiUBMiusS1A== + +esbuild-linux-arm@0.15.10: + version "0.15.10" + resolved "https://registry.yarnpkg.com/esbuild-linux-arm/-/esbuild-linux-arm-0.15.10.tgz#40a9270da3c8ffa32cf72e24a79883e323dff08d" + integrity sha512-6N8vThLL/Lysy9y4Ex8XoLQAlbZKUyExCWyayGi2KgTBelKpPgj6RZnUaKri0dHNPGgReJriKVU6+KDGQwn10A== + +esbuild-linux-mips64le@0.15.10: + version "0.15.10" + resolved "https://registry.yarnpkg.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.10.tgz#90ce1c4ee0202edb4ac69807dea77f7e5804abc4" + integrity sha512-BxP+LbaGVGIdQNJUNF7qpYjEGWb0YyHVSKqYKrn+pTwH/SiHUxFyJYSP3pqkku61olQiSBnSmWZ+YUpj78Tw7Q== + +esbuild-linux-ppc64le@0.15.10: + version "0.15.10" + resolved "https://registry.yarnpkg.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.10.tgz#782837ae7bd5b279178106c9dd801755a21fabdf" + integrity sha512-LoSQCd6498PmninNgqd/BR7z3Bsk/mabImBWuQ4wQgmQEeanzWd5BQU2aNi9mBURCLgyheuZS6Xhrw5luw3OkQ== + +esbuild-linux-riscv64@0.15.10: + version "0.15.10" + resolved "https://registry.yarnpkg.com/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.10.tgz#d7420d806ece5174f24f4634303146f915ab4207" + integrity sha512-Lrl9Cr2YROvPV4wmZ1/g48httE8z/5SCiXIyebiB5N8VT7pX3t6meI7TQVHw/wQpqP/AF4SksDuFImPTM7Z32Q== + +esbuild-linux-s390x@0.15.10: + version "0.15.10" + resolved "https://registry.yarnpkg.com/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.10.tgz#21fdf0cb3494a7fb520a71934e4dffce67fe47be" + integrity sha512-ReP+6q3eLVVP2lpRrvl5EodKX7EZ1bS1/z5j6hsluAlZP5aHhk6ghT6Cq3IANvvDdscMMCB4QEbI+AjtvoOFpA== + +esbuild-netbsd-64@0.15.10: + version "0.15.10" + resolved "https://registry.yarnpkg.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.10.tgz#6c06b3107e3df53de381e6299184d4597db0440f" + integrity sha512-iGDYtJCMCqldMskQ4eIV+QSS/CuT7xyy9i2/FjpKvxAuCzrESZXiA1L64YNj6/afuzfBe9i8m/uDkFHy257hTw== + +esbuild-openbsd-64@0.15.10: + version "0.15.10" + resolved "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.10.tgz#4daef5f5d8e74bbda53b65160029445d582570cf" + integrity sha512-ftMMIwHWrnrYnvuJQRJs/Smlcb28F9ICGde/P3FUTCgDDM0N7WA0o9uOR38f5Xe2/OhNCgkjNeb7QeaE3cyWkQ== + +esbuild-sunos-64@0.15.10: + version "0.15.10" + resolved "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.15.10.tgz#5fe7bef267a02f322fd249a8214d0274937388a7" + integrity sha512-mf7hBL9Uo2gcy2r3rUFMjVpTaGpFJJE5QTDDqUFf1632FxteYANffDZmKbqX0PfeQ2XjUDE604IcE7OJeoHiyg== + +esbuild-windows-32@0.15.10: + version "0.15.10" + resolved "https://registry.yarnpkg.com/esbuild-windows-32/-/esbuild-windows-32-0.15.10.tgz#48e3dde25ab0135579a288b30ab6ddef6d1f0b28" + integrity sha512-ttFVo+Cg8b5+qHmZHbEc8Vl17kCleHhLzgT8X04y8zudEApo0PxPg9Mz8Z2cKH1bCYlve1XL8LkyXGFjtUYeGg== + +esbuild-windows-64@0.15.10: + version "0.15.10" + resolved "https://registry.yarnpkg.com/esbuild-windows-64/-/esbuild-windows-64-0.15.10.tgz#387a9515bef3fee502d277a5d0a2db49a4ecda05" + integrity sha512-2H0gdsyHi5x+8lbng3hLbxDWR7mKHWh5BXZGKVG830KUmXOOWFE2YKJ4tHRkejRduOGDrBvHBriYsGtmTv3ntA== + +esbuild-windows-arm64@0.15.10: + version "0.15.10" + resolved "https://registry.yarnpkg.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.10.tgz#5a6fcf2fa49e895949bf5495cf088ab1b43ae879" + integrity sha512-S+th4F+F8VLsHLR0zrUcG+Et4hx0RKgK1eyHc08kztmLOES8BWwMiaGdoW9hiXuzznXQ0I/Fg904MNbr11Nktw== + +esbuild@^0.15.10: + version "0.15.10" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.15.10.tgz#85c2f8446e9b1fe04fae68daceacba033eedbd42" + integrity sha512-N7wBhfJ/E5fzn/SpNgX+oW2RLRjwaL8Y0ezqNqhjD6w0H2p0rDuEz2FKZqpqLnO8DCaWumKe8dsC/ljvVSSxng== + optionalDependencies: + "@esbuild/android-arm" "0.15.10" + "@esbuild/linux-loong64" "0.15.10" + esbuild-android-64 "0.15.10" + esbuild-android-arm64 "0.15.10" + esbuild-darwin-64 "0.15.10" + esbuild-darwin-arm64 "0.15.10" + esbuild-freebsd-64 "0.15.10" + esbuild-freebsd-arm64 "0.15.10" + esbuild-linux-32 "0.15.10" + esbuild-linux-64 "0.15.10" + esbuild-linux-arm "0.15.10" + esbuild-linux-arm64 "0.15.10" + esbuild-linux-mips64le "0.15.10" + esbuild-linux-ppc64le "0.15.10" + esbuild-linux-riscv64 "0.15.10" + esbuild-linux-s390x "0.15.10" + esbuild-netbsd-64 "0.15.10" + esbuild-openbsd-64 "0.15.10" + esbuild-sunos-64 "0.15.10" + esbuild-windows-32 "0.15.10" + esbuild-windows-64 "0.15.10" + esbuild-windows-arm64 "0.15.10" + +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + +faye-websocket@0.11.4: + version "0.11.4" + resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.4.tgz#7f0d9275cfdd86a1c963dc8b65fcc451edcbb1da" + integrity sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g== + dependencies: + websocket-driver ">=0.5.1" + +firebase@9: + version "9.10.0" + resolved "https://registry.yarnpkg.com/firebase/-/firebase-9.10.0.tgz#07e22bddce3cc1f380c440edc6286c09ac6cce8f" + integrity sha512-oSuED6BT+gQrOoXPV/xkxBLMk03A9nDXosW0xy4loQtGRJr9gW6JXgEOr0nmXFMTGzP87CpoC8Kd6y7XKSAeqQ== + dependencies: + "@firebase/analytics" "0.8.0" + "@firebase/analytics-compat" "0.1.13" + "@firebase/app" "0.7.33" + "@firebase/app-check" "0.5.12" + "@firebase/app-check-compat" "0.2.12" + "@firebase/app-compat" "0.1.34" + "@firebase/app-types" "0.7.0" + "@firebase/auth" "0.20.7" + "@firebase/auth-compat" "0.2.20" + "@firebase/database" "0.13.6" + "@firebase/database-compat" "0.2.6" + "@firebase/firestore" "3.5.0" + "@firebase/firestore-compat" "0.1.25" + "@firebase/functions" "0.8.4" + "@firebase/functions-compat" "0.2.4" + "@firebase/installations" "0.5.12" + "@firebase/installations-compat" "0.1.12" + "@firebase/messaging" "0.9.16" + "@firebase/messaging-compat" "0.1.16" + "@firebase/performance" "0.5.12" + "@firebase/performance-compat" "0.1.12" + "@firebase/remote-config" "0.3.11" + "@firebase/remote-config-compat" "0.1.12" + "@firebase/storage" "0.9.9" + "@firebase/storage-compat" "0.1.17" + "@firebase/util" "1.6.3" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + +get-caller-file@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +glob@^7.1.3: + version "7.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + +http-parser-js@>=0.5.1: + version "0.5.8" + resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.8.tgz#af23090d9ac4e24573de6f6aecc9d84a48bf20e3" + integrity sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q== + +idb@7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/idb/-/idb-7.0.1.tgz#d2875b3a2f205d854ee307f6d196f246fea590a7" + integrity sha512-UUxlE7vGWK5RfB/fDwEGgRf84DY/ieqNha6msMV99UsEMQhJ1RwbCd8AYBj3QMgnE3VZnfQvm4oKVCJTYlqIgg== + +immediate@~3.0.5: + version "3.0.6" + resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b" + integrity sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@~2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== + +jszip@^3.6.0: + version "3.10.1" + resolved "https://registry.yarnpkg.com/jszip/-/jszip-3.10.1.tgz#34aee70eb18ea1faec2f589208a157d1feb091c2" + integrity sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g== + dependencies: + lie "~3.3.0" + pako "~1.0.2" + readable-stream "~2.3.6" + setimmediate "^1.0.5" + +lie@~3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/lie/-/lie-3.3.0.tgz#dcf82dee545f46074daf200c7c1c5a08e0f40f6a" + integrity sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ== + dependencies: + immediate "~3.0.5" + +lodash.camelcase@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" + integrity sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA== + +long@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" + integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA== + +long@^5.0.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/long/-/long-5.2.0.tgz#2696dadf4b4da2ce3f6f6b89186085d94d52fd61" + integrity sha512-9RTUNjK60eJbx3uz+TEGF7fUr29ZDxR5QzXcyDpeSfeH28S9ycINflOgOlppit5U+4kNTe83KQnMEerw7GmE8w== + +minimatch@^3.1.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +node-fetch@2.6.7: + version "2.6.7" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" + integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== + dependencies: + whatwg-url "^5.0.0" + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + +pako@~1.0.2: + version "1.0.11" + resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" + integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +protobufjs@^6.11.3: + version "6.11.3" + resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.11.3.tgz#637a527205a35caa4f3e2a9a4a13ddffe0e7af74" + integrity sha512-xL96WDdCZYdU7Slin569tFX712BxsxslWwAfAhCYjQKGTq7dAU91Lomy6nLLhh/dyGhk/YH4TwTSRxTzhuHyZg== + dependencies: + "@protobufjs/aspromise" "^1.1.2" + "@protobufjs/base64" "^1.1.2" + "@protobufjs/codegen" "^2.0.4" + "@protobufjs/eventemitter" "^1.1.0" + "@protobufjs/fetch" "^1.1.0" + "@protobufjs/float" "^1.0.2" + "@protobufjs/inquire" "^1.1.0" + "@protobufjs/path" "^1.1.2" + "@protobufjs/pool" "^1.1.0" + "@protobufjs/utf8" "^1.1.0" + "@types/long" "^4.0.1" + "@types/node" ">=13.7.0" + long "^4.0.0" + +protobufjs@^7.0.0: + version "7.1.2" + resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-7.1.2.tgz#a0cf6aeaf82f5625bffcf5a38b7cd2a7de05890c" + integrity sha512-4ZPTPkXCdel3+L81yw3dG6+Kq3umdWKh7Dc7GW/CpNk4SX3hK58iPCWeCyhVTDrbkNeKrYNZ7EojM5WDaEWTLQ== + dependencies: + "@protobufjs/aspromise" "^1.1.2" + "@protobufjs/base64" "^1.1.2" + "@protobufjs/codegen" "^2.0.4" + "@protobufjs/eventemitter" "^1.1.0" + "@protobufjs/fetch" "^1.1.0" + "@protobufjs/float" "^1.0.2" + "@protobufjs/inquire" "^1.1.0" + "@protobufjs/path" "^1.1.2" + "@protobufjs/pool" "^1.1.0" + "@protobufjs/utf8" "^1.1.0" + "@types/node" ">=13.7.0" + long "^5.0.0" + +readable-stream@~2.3.6: + version "2.3.7" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" + integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== + +rimraf@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +safe-buffer@>=5.1.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +selenium-webdriver@4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/selenium-webdriver/-/selenium-webdriver-4.1.2.tgz#d463b4335632d2ea41a9e988e435a55dc41f5314" + integrity sha512-e4Ap8vQvhipgBB8Ry9zBiKGkU6kHKyNnWiavGGLKkrdW81Zv7NVMtFOL/j3yX0G8QScM7XIXijKssNd4EUxSOw== + dependencies: + jszip "^3.6.0" + tmp "^0.2.1" + ws ">=7.4.6" + +setimmediate@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + integrity sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA== + +string-width@^4.1.0, string-width@^4.2.0: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +tmp@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14" + integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ== + dependencies: + rimraf "^3.0.0" + +tr46@~0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" + integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== + +tslib@^2.1.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" + integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== + +util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== + +webidl-conversions@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" + integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== + +websocket-driver@>=0.5.1: + version "0.7.4" + resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.4.tgz#89ad5295bbf64b480abcba31e4953aca706f5760" + integrity sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg== + dependencies: + http-parser-js ">=0.5.1" + safe-buffer ">=5.1.0" + websocket-extensions ">=0.1.1" + +websocket-extensions@>=0.1.1: + version "0.1.4" + resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42" + integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg== + +whatwg-url@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" + integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== + dependencies: + tr46 "~0.0.3" + webidl-conversions "^3.0.0" + +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + +ws@>=7.4.6: + version "8.9.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.9.0.tgz#2a994bb67144be1b53fe2d23c53c028adeb7f45e" + integrity sha512-Ja7nszREasGaYUYCI2k4lCKIRTt+y7XuqVoHR44YpI49TtryyqbqvDMn5eqfW7e6HzTukDRIsXqzVHScqRcafg== + +y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== + +yargs-parser@^20.2.2: + version "20.2.9" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" + integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== + +yargs@^16.2.0: + version "16.2.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" + integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.0" + y18n "^5.0.5" + yargs-parser "^20.2.2" diff --git a/packages/firebase_messaging/firebase_messaging/example/web/firebase-messaging-sw.js b/packages/firebase_messaging/firebase_messaging/example/web/firebase-messaging-sw.js index c34730d651f4..944b809b0a0b 100644 --- a/packages/firebase_messaging/firebase_messaging/example/web/firebase-messaging-sw.js +++ b/packages/firebase_messaging/firebase_messaging/example/web/firebase-messaging-sw.js @@ -1,19 +1,96 @@ -importScripts("https://www.gstatic.com/firebasejs/8.10.0/firebase-app.js"); -importScripts("https://www.gstatic.com/firebasejs/8.10.0/firebase-messaging.js"); - -firebase.initializeApp({ - apiKey: "AIzaSyAgUhHU8wSJgO5MVNy95tMT07NEjzMOfz0", - authDomain: "react-native-firebase-testing.firebaseapp.com", - databaseURL: "https://react-native-firebase-testing.firebaseio.com", - projectId: "react-native-firebase-testing", - storageBucket: "react-native-firebase-testing.appspot.com", - messagingSenderId: "448618578101", - appId: "1:448618578101:web:ecaffe2bc4511738", -}); -// Necessary to receive background messages: -const messaging = firebase.messaging(); - -// Optional: -messaging.onBackgroundMessage((m) => { - console.log("onBackgroundMessage", m); -}); +var ke=function(e){let t=[],n=0;for(let r=0;r>6|192,t[n++]=i&63|128):(i&64512)===55296&&r+1>18|240,t[n++]=i>>12&63|128,t[n++]=i>>6&63|128,t[n++]=i&63|128):(t[n++]=i>>12|224,t[n++]=i>>6&63|128,t[n++]=i&63|128)}return t},Et=function(e){let t=[],n=0,r=0;for(;n191&&i<224){let o=e[n++];t[r++]=String.fromCharCode((i&31)<<6|o&63)}else if(i>239&&i<365){let o=e[n++],s=e[n++],a=e[n++],u=((i&7)<<18|(o&63)<<12|(s&63)<<6|a&63)-65536;t[r++]=String.fromCharCode(55296+(u>>10)),t[r++]=String.fromCharCode(56320+(u&1023))}else{let o=e[n++],s=e[n++];t[r++]=String.fromCharCode((i&15)<<12|(o&63)<<6|s&63)}}return t.join("")},It={byteToCharMap_:null,charToByteMap_:null,byteToCharMapWebSafe_:null,charToByteMapWebSafe_:null,ENCODED_VALS_BASE:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",get ENCODED_VALS(){return this.ENCODED_VALS_BASE+"+/="},get ENCODED_VALS_WEBSAFE(){return this.ENCODED_VALS_BASE+"-_."},HAS_NATIVE_SUPPORT:typeof atob=="function",encodeByteArray(e,t){if(!Array.isArray(e))throw Error("encodeByteArray takes an array as a parameter");this.init_();let n=t?this.byteToCharMapWebSafe_:this.byteToCharMap_,r=[];for(let i=0;i>2,C=(o&3)<<4|a>>4,x=(a&15)<<2|f>>6,N=f&63;u||(N=64,s||(x=64)),r.push(n[c],n[C],n[x],n[N])}return r.join("")},encodeString(e,t){return this.HAS_NATIVE_SUPPORT&&!t?btoa(e):this.encodeByteArray(ke(e),t)},decodeString(e,t){return this.HAS_NATIVE_SUPPORT&&!t?atob(e):Et(this.decodeStringToByteArray(e,t))},decodeStringToByteArray(e,t){this.init_();let n=t?this.charToByteMapWebSafe_:this.charToByteMap_,r=[];for(let i=0;i>4;if(r.push(x),f!==64){let N=a<<4&240|f>>2;if(r.push(N),C!==64){let vt=f<<6&192|C;r.push(vt)}}}return r},init_(){if(!this.byteToCharMap_){this.byteToCharMap_={},this.charToByteMap_={},this.byteToCharMapWebSafe_={},this.charToByteMapWebSafe_={};for(let e=0;e=this.ENCODED_VALS_BASE.length&&(this.charToByteMap_[this.ENCODED_VALS_WEBSAFE.charAt(e)]=e,this.charToByteMapWebSafe_[this.ENCODED_VALS.charAt(e)]=e)}}},St=function(e){let t=ke(e);return It.encodeByteArray(t,!0)},G=function(e){return St(e).replace(/\./g,"")};var M=class{constructor(){this.reject=()=>{},this.resolve=()=>{},this.promise=new Promise((t,n)=>{this.resolve=t,this.reject=n})}wrapCallback(t){return(n,r)=>{n?this.reject(n):this.resolve(r),typeof t=="function"&&(this.promise.catch(()=>{}),t.length===1?t(n):t(n,r))}}};function B(){return typeof indexedDB=="object"}function R(){return new Promise((e,t)=>{try{let n=!0,r="validate-browser-context-for-indexeddb-analytics-module",i=self.indexedDB.open(r);i.onsuccess=()=>{i.result.close(),n||self.indexedDB.deleteDatabase(r),e(!0)},i.onupgradeneeded=()=>{n=!1},i.onerror=()=>{var o;t(((o=i.error)===null||o===void 0?void 0:o.message)||"")}}catch(n){t(n)}})}var At="FirebaseError",p=class extends Error{constructor(t,n,r){super(n),this.code=t,this.customData=r,this.name=At,Object.setPrototypeOf(this,p.prototype),Error.captureStackTrace&&Error.captureStackTrace(this,m.prototype.create)}},m=class{constructor(t,n,r){this.service=t,this.serviceName=n,this.errors=r}create(t,...n){let r=n[0]||{},i=`${this.service}/${t}`,o=this.errors[t],s=o?Tt(o,r):"Error",a=`${this.serviceName}: ${s} (${i}).`;return new p(i,a,r)}};function Tt(e,t){return e.replace(Dt,(n,r)=>{let i=t[r];return i!=null?String(i):`<${r}?>`})}var Dt=/\{\$([^}]+)}/g;function L(e,t){if(e===t)return!0;let n=Object.keys(e),r=Object.keys(t);for(let i of n){if(!r.includes(i))return!1;let o=e[i],s=t[i];if(Ce(o)&&Ce(s)){if(!L(o,s))return!1}else if(o!==s)return!1}for(let i of r)if(!n.includes(i))return!1;return!0}function Ce(e){return e!==null&&typeof e=="object"}var ri=4*60*60*1e3;function P(e){return e&&e._delegate?e._delegate:e}var d=class{constructor(t,n,r){this.name=t,this.instanceFactory=n,this.type=r,this.multipleInstances=!1,this.serviceProps={},this.instantiationMode="LAZY",this.onInstanceCreated=null}setInstantiationMode(t){return this.instantiationMode=t,this}setMultipleInstances(t){return this.multipleInstances=t,this}setServiceProps(t){return this.serviceProps=t,this}setInstanceCreatedCallback(t){return this.onInstanceCreated=t,this}};var _="[DEFAULT]";var J=class{constructor(t,n){this.name=t,this.container=n,this.component=null,this.instances=new Map,this.instancesDeferred=new Map,this.instancesOptions=new Map,this.onInitCallbacks=new Map}get(t){let n=this.normalizeInstanceIdentifier(t);if(!this.instancesDeferred.has(n)){let r=new M;if(this.instancesDeferred.set(n,r),this.isInitialized(n)||this.shouldAutoInitialize())try{let i=this.getOrInitializeService({instanceIdentifier:n});i&&r.resolve(i)}catch{}}return this.instancesDeferred.get(n).promise}getImmediate(t){var n;let r=this.normalizeInstanceIdentifier(t?.identifier),i=(n=t?.optional)!==null&&n!==void 0?n:!1;if(this.isInitialized(r)||this.shouldAutoInitialize())try{return this.getOrInitializeService({instanceIdentifier:r})}catch(o){if(i)return null;throw o}else{if(i)return null;throw Error(`Service ${this.name} is not available`)}}getComponent(){return this.component}setComponent(t){if(t.name!==this.name)throw Error(`Mismatching Component ${t.name} for Provider ${this.name}.`);if(this.component)throw Error(`Component for ${this.name} has already been provided`);if(this.component=t,!!this.shouldAutoInitialize()){if(kt(t))try{this.getOrInitializeService({instanceIdentifier:_})}catch{}for(let[n,r]of this.instancesDeferred.entries()){let i=this.normalizeInstanceIdentifier(n);try{let o=this.getOrInitializeService({instanceIdentifier:i});r.resolve(o)}catch{}}}}clearInstance(t=_){this.instancesDeferred.delete(t),this.instancesOptions.delete(t),this.instances.delete(t)}async delete(){let t=Array.from(this.instances.values());await Promise.all([...t.filter(n=>"INTERNAL"in n).map(n=>n.INTERNAL.delete()),...t.filter(n=>"_delete"in n).map(n=>n._delete())])}isComponentSet(){return this.component!=null}isInitialized(t=_){return this.instances.has(t)}getOptions(t=_){return this.instancesOptions.get(t)||{}}initialize(t={}){let{options:n={}}=t,r=this.normalizeInstanceIdentifier(t.instanceIdentifier);if(this.isInitialized(r))throw Error(`${this.name}(${r}) has already been initialized`);if(!this.isComponentSet())throw Error(`Component ${this.name} has not been registered yet`);let i=this.getOrInitializeService({instanceIdentifier:r,options:n});for(let[o,s]of this.instancesDeferred.entries()){let a=this.normalizeInstanceIdentifier(o);r===a&&s.resolve(i)}return i}onInit(t,n){var r;let i=this.normalizeInstanceIdentifier(n),o=(r=this.onInitCallbacks.get(i))!==null&&r!==void 0?r:new Set;o.add(t),this.onInitCallbacks.set(i,o);let s=this.instances.get(i);return s&&t(s,i),()=>{o.delete(t)}}invokeOnInitCallbacks(t,n){let r=this.onInitCallbacks.get(n);if(!!r)for(let i of r)try{i(t,n)}catch{}}getOrInitializeService({instanceIdentifier:t,options:n={}}){let r=this.instances.get(t);if(!r&&this.component&&(r=this.component.instanceFactory(this.container,{instanceIdentifier:Ct(t),options:n}),this.instances.set(t,r),this.instancesOptions.set(t,n),this.invokeOnInitCallbacks(r,t),this.component.onInstanceCreated))try{this.component.onInstanceCreated(this.container,t,r)}catch{}return r||null}normalizeInstanceIdentifier(t=_){return this.component?this.component.multipleInstances?t:_:t}shouldAutoInitialize(){return!!this.component&&this.component.instantiationMode!=="EXPLICIT"}};function Ct(e){return e===_?void 0:e}function kt(e){return e.instantiationMode==="EAGER"}var j=class{constructor(t){this.name=t,this.providers=new Map}addComponent(t){let n=this.getProvider(t.name);if(n.isComponentSet())throw new Error(`Component ${t.name} has already been registered with ${this.name}`);n.setComponent(t)}addOrOverwriteComponent(t){this.getProvider(t.name).isComponentSet()&&this.providers.delete(t.name),this.addComponent(t)}getProvider(t){if(this.providers.has(t))return this.providers.get(t);let n=new J(t,this);return this.providers.set(t,n),n}getProviders(){return Array.from(this.providers.values())}};var Ot=[],l;(function(e){e[e.DEBUG=0]="DEBUG",e[e.VERBOSE=1]="VERBOSE",e[e.INFO=2]="INFO",e[e.WARN=3]="WARN",e[e.ERROR=4]="ERROR",e[e.SILENT=5]="SILENT"})(l||(l={}));var xt={debug:l.DEBUG,verbose:l.VERBOSE,info:l.INFO,warn:l.WARN,error:l.ERROR,silent:l.SILENT},Nt=l.INFO,Mt={[l.DEBUG]:"log",[l.VERBOSE]:"log",[l.INFO]:"info",[l.WARN]:"warn",[l.ERROR]:"error"},Bt=(e,t,...n)=>{if(tt.some(n=>e instanceof n),Oe,xe;function Lt(){return Oe||(Oe=[IDBDatabase,IDBObjectStore,IDBIndex,IDBCursor,IDBTransaction])}function Pt(){return xe||(xe=[IDBCursor.prototype.advance,IDBCursor.prototype.continue,IDBCursor.prototype.continuePrimaryKey])}var Ne=new WeakMap,Q=new WeakMap,Me=new WeakMap,Y=new WeakMap,Z=new WeakMap;function jt(e){let t=new Promise((n,r)=>{let i=()=>{e.removeEventListener("success",o),e.removeEventListener("error",s)},o=()=>{n(g(e.result)),i()},s=()=>{r(e.error),i()};e.addEventListener("success",o),e.addEventListener("error",s)});return t.then(n=>{n instanceof IDBCursor&&Ne.set(n,e)}).catch(()=>{}),Z.set(t,e),t}function $t(e){if(Q.has(e))return;let t=new Promise((n,r)=>{let i=()=>{e.removeEventListener("complete",o),e.removeEventListener("error",s),e.removeEventListener("abort",s)},o=()=>{n(),i()},s=()=>{r(e.error||new DOMException("AbortError","AbortError")),i()};e.addEventListener("complete",o),e.addEventListener("error",s),e.addEventListener("abort",s)});Q.set(e,t)}var X={get(e,t,n){if(e instanceof IDBTransaction){if(t==="done")return Q.get(e);if(t==="objectStoreNames")return e.objectStoreNames||Me.get(e);if(t==="store")return n.objectStoreNames[1]?void 0:n.objectStore(n.objectStoreNames[0])}return g(e[t])},set(e,t,n){return e[t]=n,!0},has(e,t){return e instanceof IDBTransaction&&(t==="done"||t==="store")?!0:t in e}};function Be(e){X=e(X)}function Ft(e){return e===IDBDatabase.prototype.transaction&&!("objectStoreNames"in IDBTransaction.prototype)?function(t,...n){let r=e.call(F(this),t,...n);return Me.set(r,t.sort?t.sort():[t]),g(r)}:Pt().includes(e)?function(...t){return e.apply(F(this),t),g(Ne.get(this))}:function(...t){return g(e.apply(F(this),t))}}function Ht(e){return typeof e=="function"?Ft(e):(e instanceof IDBTransaction&&$t(e),Rt(e,Lt())?new Proxy(e,X):e)}function g(e){if(e instanceof IDBRequest)return jt(e);if(Y.has(e))return Y.get(e);let t=Ht(e);return t!==e&&(Y.set(e,t),Z.set(t,e)),t}var F=e=>Z.get(e);function v(e,t,{blocked:n,upgrade:r,blocking:i,terminated:o}={}){let s=indexedDB.open(e,t),a=g(s);return r&&s.addEventListener("upgradeneeded",u=>{r(g(s.result),u.oldVersion,u.newVersion,g(s.transaction))}),n&&s.addEventListener("blocked",()=>n()),a.then(u=>{o&&u.addEventListener("close",()=>o()),i&&u.addEventListener("versionchange",()=>i())}).catch(()=>{}),a}function H(e,{blocked:t}={}){let n=indexedDB.deleteDatabase(e);return t&&n.addEventListener("blocked",()=>t()),g(n).then(()=>{})}var Vt=["get","getKey","getAll","getAllKeys","count"],Ut=["put","add","delete","clear"],ee=new Map;function Re(e,t){if(!(e instanceof IDBDatabase&&!(t in e)&&typeof t=="string"))return;if(ee.get(t))return ee.get(t);let n=t.replace(/FromIndex$/,""),r=t!==n,i=Ut.includes(n);if(!(n in(r?IDBIndex:IDBObjectStore).prototype)||!(i||Vt.includes(n)))return;let o=async function(s,...a){let u=this.transaction(s,i?"readwrite":"readonly"),f=u.store;return r&&(f=f.index(a.shift())),(await Promise.all([f[n](...a),i&&u.done]))[0]};return ee.set(t,o),o}Be(e=>({...e,get:(t,n,r)=>Re(t,n)||e.get(t,n,r),has:(t,n)=>!!Re(t,n)||e.has(t,n)}));var ne=class{constructor(t){this.container=t}getPlatformInfoString(){return this.container.getProviders().map(n=>{if(zt(n)){let r=n.getImmediate();return`${r.library}/${r.version}`}else return null}).filter(n=>n).join(" ")}};function zt(e){let t=e.getComponent();return t?.type==="VERSION"}var re="@firebase/app",Le="0.7.33";var E=new $("@firebase/app"),Kt="@firebase/app-compat",Wt="@firebase/analytics-compat",qt="@firebase/analytics",Gt="@firebase/app-check-compat",Jt="@firebase/app-check",Yt="@firebase/auth",Qt="@firebase/auth-compat",Xt="@firebase/database",Zt="@firebase/database-compat",en="@firebase/functions",tn="@firebase/functions-compat",nn="@firebase/installations",rn="@firebase/installations-compat",on="@firebase/messaging",sn="@firebase/messaging-compat",an="@firebase/performance",cn="@firebase/performance-compat",un="@firebase/remote-config",fn="@firebase/remote-config-compat",ln="@firebase/storage",dn="@firebase/storage-compat",hn="@firebase/firestore",pn="@firebase/firestore-compat",gn="firebase";var Fe="[DEFAULT]",mn={[re]:"fire-core",[Kt]:"fire-core-compat",[qt]:"fire-analytics",[Wt]:"fire-analytics-compat",[Jt]:"fire-app-check",[Gt]:"fire-app-check-compat",[Yt]:"fire-auth",[Qt]:"fire-auth-compat",[Xt]:"fire-rtdb",[Zt]:"fire-rtdb-compat",[en]:"fire-fn",[tn]:"fire-fn-compat",[nn]:"fire-iid",[rn]:"fire-iid-compat",[on]:"fire-fcm",[sn]:"fire-fcm-compat",[an]:"fire-perf",[cn]:"fire-perf-compat",[un]:"fire-rc",[fn]:"fire-rc-compat",[ln]:"fire-gcs",[dn]:"fire-gcs-compat",[hn]:"fire-fst",[pn]:"fire-fst-compat","fire-js":"fire-js",[gn]:"fire-js-all"};var V=new Map,ie=new Map;function bn(e,t){try{e.container.addComponent(t)}catch(n){E.debug(`Component ${t.name} failed to register with FirebaseApp ${e.name}`,n)}}function y(e){let t=e.name;if(ie.has(t))return E.debug(`There were multiple attempts to register component ${t}.`),!1;ie.set(t,e);for(let n of V.values())bn(n,e);return!0}function O(e,t){let n=e.container.getProvider("heartbeat").getImmediate({optional:!0});return n&&n.triggerHeartbeat(),e.container.getProvider(t)}var wn={["no-app"]:"No Firebase App '{$appName}' has been created - call Firebase App.initializeApp()",["bad-app-name"]:"Illegal App name: '{$appName}",["duplicate-app"]:"Firebase App named '{$appName}' already exists with different options or config",["app-deleted"]:"Firebase App named '{$appName}' already deleted",["invalid-app-argument"]:"firebase.{$appName}() takes either no argument or a Firebase App instance.",["invalid-log-argument"]:"First argument to `onLog` must be null or a function.",["idb-open"]:"Error thrown when opening IndexedDB. Original error: {$originalErrorMessage}.",["idb-get"]:"Error thrown when reading from IndexedDB. Original error: {$originalErrorMessage}.",["idb-set"]:"Error thrown when writing to IndexedDB. Original error: {$originalErrorMessage}.",["idb-delete"]:"Error thrown when deleting from IndexedDB. Original error: {$originalErrorMessage}."},I=new m("app","Firebase",wn);var oe=class{constructor(t,n,r){this._isDeleted=!1,this._options=Object.assign({},t),this._config=Object.assign({},n),this._name=n.name,this._automaticDataCollectionEnabled=n.automaticDataCollectionEnabled,this._container=r,this.container.addComponent(new d("app",()=>this,"PUBLIC"))}get automaticDataCollectionEnabled(){return this.checkDestroyed(),this._automaticDataCollectionEnabled}set automaticDataCollectionEnabled(t){this.checkDestroyed(),this._automaticDataCollectionEnabled=t}get name(){return this.checkDestroyed(),this._name}get options(){return this.checkDestroyed(),this._options}get config(){return this.checkDestroyed(),this._config}get container(){return this._container}get isDeleted(){return this._isDeleted}set isDeleted(t){this._isDeleted=t}checkDestroyed(){if(this.isDeleted)throw I.create("app-deleted",{appName:this._name})}};function He(e,t={}){typeof t!="object"&&(t={name:t});let n=Object.assign({name:Fe,automaticDataCollectionEnabled:!1},t),r=n.name;if(typeof r!="string"||!r)throw I.create("bad-app-name",{appName:String(r)});let i=V.get(r);if(i){if(L(e,i.options)&&L(n,i.config))return i;throw I.create("duplicate-app",{appName:r})}let o=new j(r);for(let a of ie.values())o.addComponent(a);let s=new oe(e,n,o);return V.set(r,s),s}function ce(e=Fe){let t=V.get(e);if(!t)throw I.create("no-app",{appName:e});return t}function w(e,t,n){var r;let i=(r=mn[e])!==null&&r!==void 0?r:e;n&&(i+=`-${n}`);let o=i.match(/\s|\//),s=t.match(/\s|\//);if(o||s){let a=[`Unable to register library "${i}" with version "${t}":`];o&&a.push(`library name "${i}" contains illegal characters (whitespace or "/")`),o&&s&&a.push("and"),s&&a.push(`version name "${t}" contains illegal characters (whitespace or "/")`),E.warn(a.join(" "));return}y(new d(`${i}-version`,()=>({library:i,version:t}),"VERSION"))}var yn="firebase-heartbeat-database",_n=1,k="firebase-heartbeat-store",te=null;function Ve(){return te||(te=v(yn,_n,{upgrade:(e,t)=>{switch(t){case 0:e.createObjectStore(k)}}}).catch(e=>{throw I.create("idb-open",{originalErrorMessage:e.message})})),te}async function vn(e){var t;try{return(await Ve()).transaction(k).objectStore(k).get(Ue(e))}catch(n){if(n instanceof p)E.warn(n.message);else{let r=I.create("idb-get",{originalErrorMessage:(t=n)===null||t===void 0?void 0:t.message});E.warn(r.message)}}}async function Pe(e,t){var n;try{let i=(await Ve()).transaction(k,"readwrite");return await i.objectStore(k).put(t,Ue(e)),i.done}catch(r){if(r instanceof p)E.warn(r.message);else{let i=I.create("idb-set",{originalErrorMessage:(n=r)===null||n===void 0?void 0:n.message});E.warn(i.message)}}}function Ue(e){return`${e.name}!${e.options.appId}`}var En=1024,In=30*24*60*60*1e3,se=class{constructor(t){this.container=t,this._heartbeatsCache=null;let n=this.container.getProvider("app").getImmediate();this._storage=new ae(n),this._heartbeatsCachePromise=this._storage.read().then(r=>(this._heartbeatsCache=r,r))}async triggerHeartbeat(){let n=this.container.getProvider("platform-logger").getImmediate().getPlatformInfoString(),r=je();if(this._heartbeatsCache===null&&(this._heartbeatsCache=await this._heartbeatsCachePromise),!(this._heartbeatsCache.lastSentHeartbeatDate===r||this._heartbeatsCache.heartbeats.some(i=>i.date===r)))return this._heartbeatsCache.heartbeats.push({date:r,agent:n}),this._heartbeatsCache.heartbeats=this._heartbeatsCache.heartbeats.filter(i=>{let o=new Date(i.date).valueOf();return Date.now()-o<=In}),this._storage.overwrite(this._heartbeatsCache)}async getHeartbeatsHeader(){if(this._heartbeatsCache===null&&await this._heartbeatsCachePromise,this._heartbeatsCache===null||this._heartbeatsCache.heartbeats.length===0)return"";let t=je(),{heartbeatsToSend:n,unsentEntries:r}=Sn(this._heartbeatsCache.heartbeats),i=G(JSON.stringify({version:2,heartbeats:n}));return this._heartbeatsCache.lastSentHeartbeatDate=t,r.length>0?(this._heartbeatsCache.heartbeats=r,await this._storage.overwrite(this._heartbeatsCache)):(this._heartbeatsCache.heartbeats=[],this._storage.overwrite(this._heartbeatsCache)),i}};function je(){return new Date().toISOString().substring(0,10)}function Sn(e,t=En){let n=[],r=e.slice();for(let i of e){let o=n.find(s=>s.agent===i.agent);if(o){if(o.dates.push(i.date),$e(n)>t){o.dates.pop();break}}else if(n.push({agent:i.agent,dates:[i.date]}),$e(n)>t){n.pop();break}r=r.slice(1)}return{heartbeatsToSend:n,unsentEntries:r}}var ae=class{constructor(t){this.app=t,this._canUseIndexedDBPromise=this.runIndexedDBEnvironmentCheck()}async runIndexedDBEnvironmentCheck(){return B()?R().then(()=>!0).catch(()=>!1):!1}async read(){return await this._canUseIndexedDBPromise?await vn(this.app)||{heartbeats:[]}:{heartbeats:[]}}async overwrite(t){var n;if(await this._canUseIndexedDBPromise){let i=await this.read();return Pe(this.app,{lastSentHeartbeatDate:(n=t.lastSentHeartbeatDate)!==null&&n!==void 0?n:i.lastSentHeartbeatDate,heartbeats:t.heartbeats})}else return}async add(t){var n;if(await this._canUseIndexedDBPromise){let i=await this.read();return Pe(this.app,{lastSentHeartbeatDate:(n=t.lastSentHeartbeatDate)!==null&&n!==void 0?n:i.lastSentHeartbeatDate,heartbeats:[...i.heartbeats,...t.heartbeats]})}else return}};function $e(e){return G(JSON.stringify({version:2,heartbeats:e})).length}function An(e){y(new d("platform-logger",t=>new ne(t),"PRIVATE")),y(new d("heartbeat",t=>new se(t),"PRIVATE")),w(re,Le,e),w(re,Le,"esm2017"),w("fire-js","")}An("");var Tn="firebase",Dn="9.10.0";w(Tn,Dn,"app");var We="@firebase/installations",de="0.5.12";var qe=1e4,Ge=`w:${de}`,Je="FIS_v2",Cn="https://firebaseinstallations.googleapis.com/v1",kn=60*60*1e3,On="installations",xn="Installations";var Nn={["missing-app-config-values"]:'Missing App configuration value: "{$valueName}"',["not-registered"]:"Firebase Installation is not registered.",["installation-not-found"]:"Firebase Installation not found.",["request-failed"]:'{$requestName} request failed with error "{$serverCode} {$serverStatus}: {$serverMessage}"',["app-offline"]:"Could not process request. Application offline.",["delete-pending-registration"]:"Can't delete installation while there is a pending registration request."},A=new m(On,xn,Nn);function Ye(e){return e instanceof p&&e.code.includes("request-failed")}function Qe({projectId:e}){return`${Cn}/projects/${e}/installations`}function Xe(e){return{token:e.token,requestStatus:2,expiresIn:Bn(e.expiresIn),creationTime:Date.now()}}async function Ze(e,t){let r=(await t.json()).error;return A.create("request-failed",{requestName:e,serverCode:r.code,serverMessage:r.message,serverStatus:r.status})}function et({apiKey:e}){return new Headers({"Content-Type":"application/json",Accept:"application/json","x-goog-api-key":e})}function Mn(e,{refreshToken:t}){let n=et(e);return n.append("Authorization",Rn(t)),n}async function tt(e){let t=await e();return t.status>=500&&t.status<600?e():t}function Bn(e){return Number(e.replace("s","000"))}function Rn(e){return`${Je} ${e}`}async function Ln({appConfig:e,heartbeatServiceProvider:t},{fid:n}){let r=Qe(e),i=et(e),o=t.getImmediate({optional:!0});if(o){let f=await o.getHeartbeatsHeader();f&&i.append("x-firebase-client",f)}let s={fid:n,authVersion:Je,appId:e.appId,sdkVersion:Ge},a={method:"POST",headers:i,body:JSON.stringify(s)},u=await tt(()=>fetch(r,a));if(u.ok){let f=await u.json();return{fid:f.fid||n,registrationStatus:2,refreshToken:f.refreshToken,authToken:Xe(f.authToken)}}else throw await Ze("Create Installation",u)}function nt(e){return new Promise(t=>{setTimeout(t,e)})}function Pn(e){return btoa(String.fromCharCode(...e)).replace(/\+/g,"-").replace(/\//g,"_")}var jn=/^[cdef][\w-]{21}$/,le="";function $n(){try{let e=new Uint8Array(17);(self.crypto||self.msCrypto).getRandomValues(e),e[0]=112+e[0]%16;let n=Fn(e);return jn.test(n)?n:le}catch{return le}}function Fn(e){return Pn(e).substr(0,22)}function z(e){return`${e.appName}!${e.appId}`}var rt=new Map;function it(e,t){let n=z(e);ot(n,t),Hn(n,t)}function ot(e,t){let n=rt.get(e);if(!!n)for(let r of n)r(t)}function Hn(e,t){let n=Vn();n&&n.postMessage({key:e,fid:t}),Un()}var S=null;function Vn(){return!S&&"BroadcastChannel"in self&&(S=new BroadcastChannel("[Firebase] FID Change"),S.onmessage=e=>{ot(e.data.key,e.data.fid)}),S}function Un(){rt.size===0&&S&&(S.close(),S=null)}var zn="firebase-installations-database",Kn=1,T="firebase-installations-store",ue=null;function he(){return ue||(ue=v(zn,Kn,{upgrade:(e,t)=>{switch(t){case 0:e.createObjectStore(T)}}})),ue}async function U(e,t){let n=z(e),i=(await he()).transaction(T,"readwrite"),o=i.objectStore(T),s=await o.get(n);return await o.put(t,n),await i.done,(!s||s.fid!==t.fid)&&it(e,t.fid),t}async function st(e){let t=z(e),r=(await he()).transaction(T,"readwrite");await r.objectStore(T).delete(t),await r.done}async function K(e,t){let n=z(e),i=(await he()).transaction(T,"readwrite"),o=i.objectStore(T),s=await o.get(n),a=t(s);return a===void 0?await o.delete(n):await o.put(a,n),await i.done,a&&(!s||s.fid!==a.fid)&&it(e,a.fid),a}async function pe(e){let t,n=await K(e.appConfig,r=>{let i=Wn(r),o=qn(e,i);return t=o.registrationPromise,o.installationEntry});return n.fid===le?{installationEntry:await t}:{installationEntry:n,registrationPromise:t}}function Wn(e){let t=e||{fid:$n(),registrationStatus:0};return at(t)}function qn(e,t){if(t.registrationStatus===0){if(!navigator.onLine){let i=Promise.reject(A.create("app-offline"));return{installationEntry:t,registrationPromise:i}}let n={fid:t.fid,registrationStatus:1,registrationTime:Date.now()},r=Gn(e,n);return{installationEntry:n,registrationPromise:r}}else return t.registrationStatus===1?{installationEntry:t,registrationPromise:Jn(e)}:{installationEntry:t}}async function Gn(e,t){try{let n=await Ln(e,t);return U(e.appConfig,n)}catch(n){throw Ye(n)&&n.customData.serverCode===409?await st(e.appConfig):await U(e.appConfig,{fid:t.fid,registrationStatus:0}),n}}async function Jn(e){let t=await ze(e.appConfig);for(;t.registrationStatus===1;)await nt(100),t=await ze(e.appConfig);if(t.registrationStatus===0){let{installationEntry:n,registrationPromise:r}=await pe(e);return r||n}return t}function ze(e){return K(e,t=>{if(!t)throw A.create("installation-not-found");return at(t)})}function at(e){return Yn(e)?{fid:e.fid,registrationStatus:0}:e}function Yn(e){return e.registrationStatus===1&&e.registrationTime+qefetch(r,a));if(u.ok){let f=await u.json();return Xe(f)}else throw await Ze("Generate Auth Token",u)}function Xn(e,{fid:t}){return`${Qe(e)}/${t}/authTokens:generate`}async function ge(e,t=!1){let n,r=await K(e.appConfig,o=>{if(!ct(o))throw A.create("not-registered");let s=o.authToken;if(!t&&tr(s))return o;if(s.requestStatus===1)return n=Zn(e,t),o;{if(!navigator.onLine)throw A.create("app-offline");let a=rr(o);return n=er(e,a),a}});return n?await n:r.authToken}async function Zn(e,t){let n=await Ke(e.appConfig);for(;n.authToken.requestStatus===1;)await nt(100),n=await Ke(e.appConfig);let r=n.authToken;return r.requestStatus===0?ge(e,t):r}function Ke(e){return K(e,t=>{if(!ct(t))throw A.create("not-registered");let n=t.authToken;return ir(n)?Object.assign(Object.assign({},t),{authToken:{requestStatus:0}}):t})}async function er(e,t){try{let n=await Qn(e,t),r=Object.assign(Object.assign({},t),{authToken:n});return await U(e.appConfig,r),n}catch(n){if(Ye(n)&&(n.customData.serverCode===401||n.customData.serverCode===404))await st(e.appConfig);else{let r=Object.assign(Object.assign({},t),{authToken:{requestStatus:0}});await U(e.appConfig,r)}throw n}}function ct(e){return e!==void 0&&e.registrationStatus===2}function tr(e){return e.requestStatus===2&&!nr(e)}function nr(e){let t=Date.now();return t{let t=e.getProvider("app").getImmediate(),n=cr(t),r=O(t,"heartbeat");return{app:t,appConfig:n,heartbeatServiceProvider:r,_delete:()=>Promise.resolve()}},lr=e=>{let t=e.getProvider("app").getImmediate(),n=O(t,ut).getImmediate();return{getId:()=>or(n),getToken:i=>sr(n,i)}};function dr(){y(new d(ut,fr,"PUBLIC")),y(new d(ur,lr,"PRIVATE"))}dr();w(We,de);w(We,de,"esm2017");var dt="BDOU99-h67HcA6JeFXHbSNMu7e2yNNu3RzoMj8TM4W88jITfq7ZmPvIM1Iv-4_l2LxQcYwhqby2xGpWwzjfAnG4",hr="https://fcmregistrations.googleapis.com/v1",ht="FCM_MSG",pr="google.c.a.c_id",gr=3,mr=1,W;(function(e){e[e.DATA_MESSAGE=1]="DATA_MESSAGE",e[e.DISPLAY_NOTIFICATION=3]="DISPLAY_NOTIFICATION"})(W||(W={}));var q;(function(e){e.PUSH_RECEIVED="push-received",e.NOTIFICATION_CLICKED="notification-clicked"})(q||(q={}));function b(e){let t=new Uint8Array(e);return btoa(String.fromCharCode(...t)).replace(/=/g,"").replace(/\+/g,"-").replace(/\//g,"_")}function br(e){let t="=".repeat((4-e.length%4)%4),n=(e+t).replace(/\-/g,"+").replace(/_/g,"/"),r=atob(n),i=new Uint8Array(r.length);for(let o=0;oo.name).includes(me))return null;let t=null;return(await v(me,wr,{upgrade:async(r,i,o,s)=>{var a;if(i<2||!r.objectStoreNames.contains(ft))return;let u=s.objectStore(ft),f=await u.index("fcmSenderId").get(e);if(await u.clear(),!!f){if(i===2){let c=f;if(!c.auth||!c.p256dh||!c.endpoint)return;t={token:c.fcmToken,createTime:(a=c.createTime)!==null&&a!==void 0?a:Date.now(),subscriptionOptions:{auth:c.auth,p256dh:c.p256dh,endpoint:c.endpoint,swScope:c.swScope,vapidKey:typeof c.vapidKey=="string"?c.vapidKey:b(c.vapidKey)}}}else if(i===3){let c=f;t={token:c.fcmToken,createTime:c.createTime,subscriptionOptions:{auth:b(c.auth),p256dh:b(c.p256dh),endpoint:c.endpoint,swScope:c.swScope,vapidKey:b(c.vapidKey)}}}else if(i===4){let c=f;t={token:c.fcmToken,createTime:c.createTime,subscriptionOptions:{auth:b(c.auth),p256dh:b(c.p256dh),endpoint:c.endpoint,swScope:c.swScope,vapidKey:b(c.vapidKey)}}}}}})).close(),await H(me),await H("fcm_vapid_details_db"),await H("undefined"),_r(t)?t:null}function _r(e){if(!e||!e.subscriptionOptions)return!1;let{subscriptionOptions:t}=e;return typeof e.createTime=="number"&&e.createTime>0&&typeof e.token=="string"&&e.token.length>0&&typeof t.auth=="string"&&t.auth.length>0&&typeof t.p256dh=="string"&&t.p256dh.length>0&&typeof t.endpoint=="string"&&t.endpoint.length>0&&typeof t.swScope=="string"&&t.swScope.length>0&&typeof t.vapidKey=="string"&&t.vapidKey.length>0}var vr="firebase-messaging-database",Er=1,D="firebase-messaging-store",be=null;function ve(){return be||(be=v(vr,Er,{upgrade:(e,t)=>{switch(t){case 0:e.createObjectStore(D)}}})),be}async function Ee(e){let t=Se(e),r=await(await ve()).transaction(D).objectStore(D).get(t);if(r)return r;{let i=await yr(e.appConfig.senderId);if(i)return await Ie(e,i),i}}async function Ie(e,t){let n=Se(e),i=(await ve()).transaction(D,"readwrite");return await i.objectStore(D).put(t,n),await i.done,t}async function Ir(e){let t=Se(e),r=(await ve()).transaction(D,"readwrite");await r.objectStore(D).delete(t),await r.done}function Se({appConfig:e}){return e.appId}var Sr={["missing-app-config-values"]:'Missing App configuration value: "{$valueName}"',["only-available-in-window"]:"This method is available in a Window context.",["only-available-in-sw"]:"This method is available in a service worker context.",["permission-default"]:"The notification permission was not granted and dismissed instead.",["permission-blocked"]:"The notification permission was not granted and blocked instead.",["unsupported-browser"]:"This browser doesn't support the API's required to use the Firebase SDK.",["indexed-db-unsupported"]:"This browser doesn't support indexedDb.open() (ex. Safari iFrame, Firefox Private Browsing, etc)",["failed-service-worker-registration"]:"We are unable to register the default service worker. {$browserErrorMessage}",["token-subscribe-failed"]:"A problem occurred while subscribing the user to FCM: {$errorInfo}",["token-subscribe-no-token"]:"FCM returned no token when subscribing the user to push.",["token-unsubscribe-failed"]:"A problem occurred while unsubscribing the user from FCM: {$errorInfo}",["token-update-failed"]:"A problem occurred while updating the user from FCM: {$errorInfo}",["token-update-no-token"]:"FCM returned no token when updating the user to push.",["use-sw-after-get-token"]:"The useServiceWorker() method may only be called once and must be called before calling getToken() to ensure your service worker is used.",["invalid-sw-registration"]:"The input to useServiceWorker() must be a ServiceWorkerRegistration.",["invalid-bg-handler"]:"The input to setBackgroundMessageHandler() must be a function.",["invalid-vapid-key"]:"The public VAPID key must be a string.",["use-vapid-key-after-get-token"]:"The usePublicVapidKey() method may only be called once and must be called before calling getToken() to ensure your VAPID key is used."},h=new m("messaging","Messaging",Sr);async function Ar(e,t){var n;let r=await Te(e),i=gt(t),o={method:"POST",headers:r,body:JSON.stringify(i)},s;try{s=await(await fetch(Ae(e.appConfig),o)).json()}catch(a){throw h.create("token-subscribe-failed",{errorInfo:(n=a)===null||n===void 0?void 0:n.toString()})}if(s.error){let a=s.error.message;throw h.create("token-subscribe-failed",{errorInfo:a})}if(!s.token)throw h.create("token-subscribe-no-token");return s.token}async function Tr(e,t){var n;let r=await Te(e),i=gt(t.subscriptionOptions),o={method:"PATCH",headers:r,body:JSON.stringify(i)},s;try{s=await(await fetch(`${Ae(e.appConfig)}/${t.token}`,o)).json()}catch(a){throw h.create("token-update-failed",{errorInfo:(n=a)===null||n===void 0?void 0:n.toString()})}if(s.error){let a=s.error.message;throw h.create("token-update-failed",{errorInfo:a})}if(!s.token)throw h.create("token-update-no-token");return s.token}async function pt(e,t){var n;let r=await Te(e),i={method:"DELETE",headers:r};try{let s=await(await fetch(`${Ae(e.appConfig)}/${t}`,i)).json();if(s.error){let a=s.error.message;throw h.create("token-unsubscribe-failed",{errorInfo:a})}}catch(o){throw h.create("token-unsubscribe-failed",{errorInfo:(n=o)===null||n===void 0?void 0:n.toString()})}}function Ae({projectId:e}){return`${hr}/projects/${e}/registrations`}async function Te({appConfig:e,installations:t}){let n=await t.getToken();return new Headers({"Content-Type":"application/json",Accept:"application/json","x-goog-api-key":e.apiKey,"x-goog-firebase-installations-auth":`FIS ${n}`})}function gt({p256dh:e,auth:t,endpoint:n,vapidKey:r}){let i={web:{endpoint:n,auth:t,p256dh:e}};return r!==dt&&(i.web.applicationPubKey=r),i}var Dr=7*24*60*60*1e3;async function Cr(e){let t=await Or(e.swRegistration,e.vapidKey),n={vapidKey:e.vapidKey,swScope:e.swRegistration.scope,endpoint:t.endpoint,auth:b(t.getKey("auth")),p256dh:b(t.getKey("p256dh"))},r=await Ee(e.firebaseDependencies);if(r){if(xr(r.subscriptionOptions,n))return Date.now()>=r.createTime+Dr?kr(e,{token:r.token,createTime:Date.now(),subscriptionOptions:n}):r.token;try{await pt(e.firebaseDependencies,r.token)}catch(i){console.warn(i)}return lt(e.firebaseDependencies,n)}else return lt(e.firebaseDependencies,n)}async function ye(e){let t=await Ee(e.firebaseDependencies);t&&(await pt(e.firebaseDependencies,t.token),await Ir(e.firebaseDependencies));let n=await e.swRegistration.pushManager.getSubscription();return n?n.unsubscribe():!0}async function kr(e,t){try{let n=await Tr(e.firebaseDependencies,t),r=Object.assign(Object.assign({},t),{token:n,createTime:Date.now()});return await Ie(e.firebaseDependencies,r),n}catch(n){throw await ye(e),n}}async function lt(e,t){let r={token:await Ar(e,t),createTime:Date.now(),subscriptionOptions:t};return await Ie(e,r),r.token}async function Or(e,t){let n=await e.pushManager.getSubscription();return n||e.pushManager.subscribe({userVisibleOnly:!0,applicationServerKey:br(t)})}function xr(e,t){let n=t.vapidKey===e.vapidKey,r=t.endpoint===e.endpoint,i=t.auth===e.auth,o=t.p256dh===e.p256dh;return n&&r&&i&&o}function Nr(e){let t={from:e.from,collapseKey:e.collapse_key,messageId:e.fcmMessageId};return Mr(t,e),Br(t,e),Rr(t,e),t}function Mr(e,t){if(!t.notification)return;e.notification={};let n=t.notification.title;n&&(e.notification.title=n);let r=t.notification.body;r&&(e.notification.body=r);let i=t.notification.image;i&&(e.notification.image=i)}function Br(e,t){!t.data||(e.data=t.data)}function Rr(e,t){var n,r,i,o,s;if(!t.fcmOptions&&!(!((n=t.notification)===null||n===void 0)&&n.click_action))return;e.fcmOptions={};let a=(i=(r=t.fcmOptions)===null||r===void 0?void 0:r.link)!==null&&i!==void 0?i:(o=t.notification)===null||o===void 0?void 0:o.click_action;a&&(e.fcmOptions.link=a);let u=(s=t.fcmOptions)===null||s===void 0?void 0:s.analytics_label;u&&(e.fcmOptions.analyticsLabel=u)}function Lr(e){return typeof e=="object"&&!!e&&pr in e}function Pr(e){return new Promise(t=>{setTimeout(t,e)})}mt("hts/frbslgigp.ogepscmv/ieo/eaylg","tp:/ieaeogn-agolai.o/1frlglgc/o");mt("AzSCbw63g1R0nCw85jG8","Iaya3yLKwmgvh7cF0q4");async function jr(e,t){let n=$r(t,await e.firebaseDependencies.installations.getId());Fr(e,n)}function $r(e,t){var n,r;let i={};return e.from&&(i.project_number=e.from),e.fcmMessageId&&(i.message_id=e.fcmMessageId),i.instance_id=t,e.notification?i.message_type=W.DISPLAY_NOTIFICATION.toString():i.message_type=W.DATA_MESSAGE.toString(),i.sdk_platform=gr.toString(),i.package_name=self.origin.replace(/(^\w+:|^)\/\//,""),e.collapse_key&&(i.collapse_key=e.collapse_key),i.event=mr.toString(),!((n=e.fcmOptions)===null||n===void 0)&&n.analytics_label&&(i.analytics_label=(r=e.fcmOptions)===null||r===void 0?void 0:r.analytics_label),i}function Fr(e,t){let n={};n.event_time_ms=Math.floor(Date.now()).toString(),n.source_extension_json_proto3=JSON.stringify(t),e.logEvents.push(n)}function mt(e,t){let n=[];for(let r=0;rt.visibilityState==="visible"&&!t.url.startsWith("chrome-extension://"))}function Gr(e,t){t.isFirebaseMessaging=!0,t.messageType=q.PUSH_RECEIVED;for(let n of e)n.postMessage(t)}function bt(){return self.clients.matchAll({type:"window",includeUncontrolled:!0})}function Jr(e){var t;let{actions:n}=e,{maxActions:r}=Notification;return n&&r&&n.length>r&&console.warn(`This browser only supports ${r} actions. The remaining actions will not be displayed.`),self.registration.showNotification((t=e.title)!==null&&t!==void 0?t:"",e)}function Yr(e){var t,n,r;let i=(n=(t=e.fcmOptions)===null||t===void 0?void 0:t.link)!==null&&n!==void 0?n:(r=e.notification)===null||r===void 0?void 0:r.click_action;return i||(Lr(e.data)?self.location.origin:null)}function Qr(e){if(!e||!e.options)throw we("App Configuration Object");if(!e.name)throw we("App Name");let t=["projectId","apiKey","appId","messagingSenderId"],{options:n}=e;for(let r of t)if(!n[r])throw we(r);return{appName:e.name,projectId:n.projectId,apiKey:n.apiKey,appId:n.appId,senderId:n.messagingSenderId}}function we(e){return h.create("missing-app-config-values",{valueName:e})}var _e=class{constructor(t,n,r){this.deliveryMetricsExportedToBigQueryEnabled=!1,this.onBackgroundMessageHandler=null,this.onMessageHandler=null,this.logEvents=[],this.isLogServiceStarted=!1;let i=Qr(t);this.firebaseDependencies={app:t,appConfig:i,installations:n,analyticsProvider:r}}_delete(){return Promise.resolve()}};var Xr=e=>{let t=new _e(e.getProvider("app").getImmediate(),e.getProvider("installations-internal").getImmediate(),e.getProvider("analytics-internal"));return self.addEventListener("push",n=>{n.waitUntil(Vr(n,t))}),self.addEventListener("pushsubscriptionchange",n=>{n.waitUntil(Hr(n,t))}),self.addEventListener("notificationclick",n=>{n.waitUntil(Ur(n))}),t};function Zr(){y(new d("messaging-sw",Xr,"PUBLIC"))}async function De(){return B()&&await R()&&"PushManager"in self&&"Notification"in self&&ServiceWorkerRegistration.prototype.hasOwnProperty("showNotification")&&PushSubscription.prototype.hasOwnProperty("getKey")}function ei(e,t){if(self.document!==void 0)throw h.create("only-available-in-sw");return e.onBackgroundMessageHandler=t,()=>{e.onBackgroundMessageHandler=null}}function ti(e,t){e.deliveryMetricsExportedToBigQueryEnabled=t}function wt(e=ce()){return De().then(t=>{if(!t)throw h.create("unsupported-browser")},t=>{throw h.create("indexed-db-unsupported")}),O(P(e),"messaging-sw").getImmediate()}function yt(e,t){return e=P(e),ei(e,t)}function _t(e,t){return e=P(e),ti(e,t)}Zr();self.addEventListener("install",e=>{console.log(self),console.log(e)});var ni=He({apiKey:"AIzaSyAgUhHU8wSJgO5MVNy95tMT07NEjzMOfz0",authDomain:"react-native-firebase-testing.firebaseapp.com",databaseURL:"https://react-native-firebase-testing.firebaseio.com",projectId:"react-native-firebase-testing",storageBucket:"react-native-firebase-testing.appspot.com",messagingSenderId:"448618578101",appId:"1:448618578101:web:ecaffe2bc4511738"});De().then(e=>{if(e){let t=wt(ni);_t(t,!0),console.log("experimental working"),yt(t,({notification:n})=>{let{title:r,body:i,image:o}=n??{};!r||self.registration.showNotification(r,{body:i,icon:o||"/assets/icons/icon-72x72.png"})})}}); +/** + * @license + * Copyright 2017 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. + */ +/** + * @license + * Copyright 2018 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. + */ +/** + * @license + * Copyright 2019 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. + */ +/** + * @license + * Copyright 2020 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. + */ +/** + * @license + * Copyright 2021 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. + */ +/** + * @license + * Copyright 2022 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. + */ +//# sourceMappingURL=firebase-messaging-sw.js.map diff --git a/packages/firebase_messaging/firebase_messaging/example/web/firebase-messaging-sw.js.map b/packages/firebase_messaging/firebase_messaging/example/web/firebase-messaging-sw.js.map new file mode 100644 index 000000000000..cffb6ab13552 --- /dev/null +++ b/packages/firebase_messaging/firebase_messaging/example/web/firebase-messaging-sw.js.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": ["../bundled-service-worker/node_modules/@firebase/util/src/constants.ts", "../bundled-service-worker/node_modules/@firebase/util/src/assert.ts", "../bundled-service-worker/node_modules/@firebase/util/src/crypt.ts", "../bundled-service-worker/node_modules/@firebase/util/src/deepCopy.ts", "../bundled-service-worker/node_modules/@firebase/util/src/deferred.ts", "../bundled-service-worker/node_modules/@firebase/util/src/emulator.ts", "../bundled-service-worker/node_modules/@firebase/util/src/environment.ts", "../bundled-service-worker/node_modules/@firebase/util/src/errors.ts", "../bundled-service-worker/node_modules/@firebase/util/src/json.ts", "../bundled-service-worker/node_modules/@firebase/util/src/jwt.ts", "../bundled-service-worker/node_modules/@firebase/util/src/obj.ts", "../bundled-service-worker/node_modules/@firebase/util/src/promise.ts", "../bundled-service-worker/node_modules/@firebase/util/src/query.ts", "../bundled-service-worker/node_modules/@firebase/util/src/sha1.ts", "../bundled-service-worker/node_modules/@firebase/util/src/subscribe.ts", "../bundled-service-worker/node_modules/@firebase/util/src/validation.ts", "../bundled-service-worker/node_modules/@firebase/util/src/utf8.ts", "../bundled-service-worker/node_modules/@firebase/util/src/uuid.ts", "../bundled-service-worker/node_modules/@firebase/util/src/exponential_backoff.ts", "../bundled-service-worker/node_modules/@firebase/util/src/formatters.ts", "../bundled-service-worker/node_modules/@firebase/util/src/compat.ts", "../bundled-service-worker/node_modules/@firebase/component/src/component.ts", "../bundled-service-worker/node_modules/@firebase/component/src/constants.ts", "../bundled-service-worker/node_modules/@firebase/component/src/provider.ts", "../bundled-service-worker/node_modules/@firebase/component/src/component_container.ts", "../bundled-service-worker/node_modules/@firebase/logger/src/logger.ts", "../bundled-service-worker/node_modules/idb/build/wrap-idb-value.js", "../bundled-service-worker/node_modules/idb/build/index.js", "../bundled-service-worker/node_modules/@firebase/app/src/platformLoggerService.ts", "../bundled-service-worker/node_modules/@firebase/app/src/logger.ts", "../bundled-service-worker/node_modules/@firebase/app/src/constants.ts", "../bundled-service-worker/node_modules/@firebase/app/src/internal.ts", "../bundled-service-worker/node_modules/@firebase/app/src/errors.ts", "../bundled-service-worker/node_modules/@firebase/app/src/firebaseApp.ts", "../bundled-service-worker/node_modules/@firebase/app/src/api.ts", "../bundled-service-worker/node_modules/@firebase/app/src/indexeddb.ts", "../bundled-service-worker/node_modules/@firebase/app/src/heartbeatService.ts", "../bundled-service-worker/node_modules/@firebase/app/src/registerCoreComponents.ts", "../bundled-service-worker/node_modules/@firebase/app/src/index.ts", "../bundled-service-worker/node_modules/firebase/app/index.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/util/constants.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/util/errors.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/functions/common.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/functions/create-installation-request.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/util/sleep.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/helpers/buffer-to-base64-url-safe.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/helpers/generate-fid.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/util/get-key.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/helpers/fid-changed.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/helpers/idb-manager.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/helpers/get-installation-entry.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/functions/generate-auth-token-request.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/helpers/refresh-auth-token.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/api/get-id.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/api/get-token.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/functions/delete-installation-request.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/api/delete-installations.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/api/on-id-change.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/api/get-installations.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/helpers/extract-app-config.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/functions/config.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/index.ts", "../bundled-service-worker/node_modules/@firebase/messaging/src/util/constants.ts", "../bundled-service-worker/node_modules/@firebase/messaging/src/interfaces/internal-message-payload.ts", "../bundled-service-worker/node_modules/@firebase/messaging/src/helpers/array-base64-translator.ts", "../bundled-service-worker/node_modules/@firebase/messaging/src/helpers/migrate-old-database.ts", "../bundled-service-worker/node_modules/@firebase/messaging/src/internals/idb-manager.ts", "../bundled-service-worker/node_modules/@firebase/messaging/src/util/errors.ts", "../bundled-service-worker/node_modules/@firebase/messaging/src/internals/requests.ts", "../bundled-service-worker/node_modules/@firebase/messaging/src/internals/token-manager.ts", "../bundled-service-worker/node_modules/@firebase/messaging/src/helpers/externalizePayload.ts", "../bundled-service-worker/node_modules/@firebase/messaging/src/helpers/is-console-message.ts", "../bundled-service-worker/node_modules/@firebase/messaging/src/helpers/sleep.ts", "../bundled-service-worker/node_modules/@firebase/messaging/src/helpers/logToFirelog.ts", "../bundled-service-worker/node_modules/@firebase/messaging/src/listeners/sw-listeners.ts", "../bundled-service-worker/node_modules/@firebase/messaging/src/helpers/extract-app-config.ts", "../bundled-service-worker/node_modules/@firebase/messaging/src/messaging-service.ts", "../bundled-service-worker/node_modules/@firebase/messaging/src/helpers/register.ts", "../bundled-service-worker/node_modules/@firebase/messaging/src/api/isSupported.ts", "../bundled-service-worker/node_modules/@firebase/messaging/src/api/onBackgroundMessage.ts", "../bundled-service-worker/node_modules/@firebase/messaging/src/api/setDeliveryMetricsExportedToBigQueryEnabled.ts", "../bundled-service-worker/node_modules/@firebase/messaging/src/api.ts", "../bundled-service-worker/node_modules/@firebase/messaging/src/index.sw.ts", "../bundled-service-worker/firebase-messaging-sw.ts"], + "sourcesContent": ["/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * @fileoverview Firebase constants. Some of these (@defines) can be overridden at compile-time.\n */\n\nexport const CONSTANTS = {\n /**\n * @define {boolean} Whether this is the client Node.js SDK.\n */\n NODE_CLIENT: false,\n /**\n * @define {boolean} Whether this is the Admin Node.js SDK.\n */\n NODE_ADMIN: false,\n\n /**\n * Firebase SDK Version\n */\n SDK_VERSION: '${JSCORE_VERSION}'\n};\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { CONSTANTS } from './constants';\n\n/**\n * Throws an error if the provided assertion is falsy\n */\nexport const assert = function (assertion: unknown, message: string): void {\n if (!assertion) {\n throw assertionError(message);\n }\n};\n\n/**\n * Returns an Error object suitable for throwing.\n */\nexport const assertionError = function (message: string): Error {\n return new Error(\n 'Firebase Database (' +\n CONSTANTS.SDK_VERSION +\n ') INTERNAL ASSERT FAILED: ' +\n message\n );\n};\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nconst stringToByteArray = function (str: string): number[] {\n // TODO(user): Use native implementations if/when available\n const out: number[] = [];\n let p = 0;\n for (let i = 0; i < str.length; i++) {\n let c = str.charCodeAt(i);\n if (c < 128) {\n out[p++] = c;\n } else if (c < 2048) {\n out[p++] = (c >> 6) | 192;\n out[p++] = (c & 63) | 128;\n } else if (\n (c & 0xfc00) === 0xd800 &&\n i + 1 < str.length &&\n (str.charCodeAt(i + 1) & 0xfc00) === 0xdc00\n ) {\n // Surrogate Pair\n c = 0x10000 + ((c & 0x03ff) << 10) + (str.charCodeAt(++i) & 0x03ff);\n out[p++] = (c >> 18) | 240;\n out[p++] = ((c >> 12) & 63) | 128;\n out[p++] = ((c >> 6) & 63) | 128;\n out[p++] = (c & 63) | 128;\n } else {\n out[p++] = (c >> 12) | 224;\n out[p++] = ((c >> 6) & 63) | 128;\n out[p++] = (c & 63) | 128;\n }\n }\n return out;\n};\n\n/**\n * Turns an array of numbers into the string given by the concatenation of the\n * characters to which the numbers correspond.\n * @param bytes Array of numbers representing characters.\n * @return Stringification of the array.\n */\nconst byteArrayToString = function (bytes: number[]): string {\n // TODO(user): Use native implementations if/when available\n const out: string[] = [];\n let pos = 0,\n c = 0;\n while (pos < bytes.length) {\n const c1 = bytes[pos++];\n if (c1 < 128) {\n out[c++] = String.fromCharCode(c1);\n } else if (c1 > 191 && c1 < 224) {\n const c2 = bytes[pos++];\n out[c++] = String.fromCharCode(((c1 & 31) << 6) | (c2 & 63));\n } else if (c1 > 239 && c1 < 365) {\n // Surrogate Pair\n const c2 = bytes[pos++];\n const c3 = bytes[pos++];\n const c4 = bytes[pos++];\n const u =\n (((c1 & 7) << 18) | ((c2 & 63) << 12) | ((c3 & 63) << 6) | (c4 & 63)) -\n 0x10000;\n out[c++] = String.fromCharCode(0xd800 + (u >> 10));\n out[c++] = String.fromCharCode(0xdc00 + (u & 1023));\n } else {\n const c2 = bytes[pos++];\n const c3 = bytes[pos++];\n out[c++] = String.fromCharCode(\n ((c1 & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)\n );\n }\n }\n return out.join('');\n};\n\ninterface Base64 {\n byteToCharMap_: { [key: number]: string } | null;\n charToByteMap_: { [key: string]: number } | null;\n byteToCharMapWebSafe_: { [key: number]: string } | null;\n charToByteMapWebSafe_: { [key: string]: number } | null;\n ENCODED_VALS_BASE: string;\n readonly ENCODED_VALS: string;\n readonly ENCODED_VALS_WEBSAFE: string;\n HAS_NATIVE_SUPPORT: boolean;\n encodeByteArray(input: number[] | Uint8Array, webSafe?: boolean): string;\n encodeString(input: string, webSafe?: boolean): string;\n decodeString(input: string, webSafe: boolean): string;\n decodeStringToByteArray(input: string, webSafe: boolean): number[];\n init_(): void;\n}\n\n// We define it as an object literal instead of a class because a class compiled down to es5 can't\n// be treeshaked. https://github.com/rollup/rollup/issues/1691\n// Static lookup maps, lazily populated by init_()\nexport const base64: Base64 = {\n /**\n * Maps bytes to characters.\n */\n byteToCharMap_: null,\n\n /**\n * Maps characters to bytes.\n */\n charToByteMap_: null,\n\n /**\n * Maps bytes to websafe characters.\n * @private\n */\n byteToCharMapWebSafe_: null,\n\n /**\n * Maps websafe characters to bytes.\n * @private\n */\n charToByteMapWebSafe_: null,\n\n /**\n * Our default alphabet, shared between\n * ENCODED_VALS and ENCODED_VALS_WEBSAFE\n */\n ENCODED_VALS_BASE:\n 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + 'abcdefghijklmnopqrstuvwxyz' + '0123456789',\n\n /**\n * Our default alphabet. Value 64 (=) is special; it means \"nothing.\"\n */\n get ENCODED_VALS() {\n return this.ENCODED_VALS_BASE + '+/=';\n },\n\n /**\n * Our websafe alphabet.\n */\n get ENCODED_VALS_WEBSAFE() {\n return this.ENCODED_VALS_BASE + '-_.';\n },\n\n /**\n * Whether this browser supports the atob and btoa functions. This extension\n * started at Mozilla but is now implemented by many browsers. We use the\n * ASSUME_* variables to avoid pulling in the full useragent detection library\n * but still allowing the standard per-browser compilations.\n *\n */\n HAS_NATIVE_SUPPORT: typeof atob === 'function',\n\n /**\n * Base64-encode an array of bytes.\n *\n * @param input An array of bytes (numbers with\n * value in [0, 255]) to encode.\n * @param webSafe Boolean indicating we should use the\n * alternative alphabet.\n * @return The base64 encoded string.\n */\n encodeByteArray(input: number[] | Uint8Array, webSafe?: boolean): string {\n if (!Array.isArray(input)) {\n throw Error('encodeByteArray takes an array as a parameter');\n }\n\n this.init_();\n\n const byteToCharMap = webSafe\n ? this.byteToCharMapWebSafe_!\n : this.byteToCharMap_!;\n\n const output = [];\n\n for (let i = 0; i < input.length; i += 3) {\n const byte1 = input[i];\n const haveByte2 = i + 1 < input.length;\n const byte2 = haveByte2 ? input[i + 1] : 0;\n const haveByte3 = i + 2 < input.length;\n const byte3 = haveByte3 ? input[i + 2] : 0;\n\n const outByte1 = byte1 >> 2;\n const outByte2 = ((byte1 & 0x03) << 4) | (byte2 >> 4);\n let outByte3 = ((byte2 & 0x0f) << 2) | (byte3 >> 6);\n let outByte4 = byte3 & 0x3f;\n\n if (!haveByte3) {\n outByte4 = 64;\n\n if (!haveByte2) {\n outByte3 = 64;\n }\n }\n\n output.push(\n byteToCharMap[outByte1],\n byteToCharMap[outByte2],\n byteToCharMap[outByte3],\n byteToCharMap[outByte4]\n );\n }\n\n return output.join('');\n },\n\n /**\n * Base64-encode a string.\n *\n * @param input A string to encode.\n * @param webSafe If true, we should use the\n * alternative alphabet.\n * @return The base64 encoded string.\n */\n encodeString(input: string, webSafe?: boolean): string {\n // Shortcut for Mozilla browsers that implement\n // a native base64 encoder in the form of \"btoa/atob\"\n if (this.HAS_NATIVE_SUPPORT && !webSafe) {\n return btoa(input);\n }\n return this.encodeByteArray(stringToByteArray(input), webSafe);\n },\n\n /**\n * Base64-decode a string.\n *\n * @param input to decode.\n * @param webSafe True if we should use the\n * alternative alphabet.\n * @return string representing the decoded value.\n */\n decodeString(input: string, webSafe: boolean): string {\n // Shortcut for Mozilla browsers that implement\n // a native base64 encoder in the form of \"btoa/atob\"\n if (this.HAS_NATIVE_SUPPORT && !webSafe) {\n return atob(input);\n }\n return byteArrayToString(this.decodeStringToByteArray(input, webSafe));\n },\n\n /**\n * Base64-decode a string.\n *\n * In base-64 decoding, groups of four characters are converted into three\n * bytes. If the encoder did not apply padding, the input length may not\n * be a multiple of 4.\n *\n * In this case, the last group will have fewer than 4 characters, and\n * padding will be inferred. If the group has one or two characters, it decodes\n * to one byte. If the group has three characters, it decodes to two bytes.\n *\n * @param input Input to decode.\n * @param webSafe True if we should use the web-safe alphabet.\n * @return bytes representing the decoded value.\n */\n decodeStringToByteArray(input: string, webSafe: boolean): number[] {\n this.init_();\n\n const charToByteMap = webSafe\n ? this.charToByteMapWebSafe_!\n : this.charToByteMap_!;\n\n const output: number[] = [];\n\n for (let i = 0; i < input.length; ) {\n const byte1 = charToByteMap[input.charAt(i++)];\n\n const haveByte2 = i < input.length;\n const byte2 = haveByte2 ? charToByteMap[input.charAt(i)] : 0;\n ++i;\n\n const haveByte3 = i < input.length;\n const byte3 = haveByte3 ? charToByteMap[input.charAt(i)] : 64;\n ++i;\n\n const haveByte4 = i < input.length;\n const byte4 = haveByte4 ? charToByteMap[input.charAt(i)] : 64;\n ++i;\n\n if (byte1 == null || byte2 == null || byte3 == null || byte4 == null) {\n throw Error();\n }\n\n const outByte1 = (byte1 << 2) | (byte2 >> 4);\n output.push(outByte1);\n\n if (byte3 !== 64) {\n const outByte2 = ((byte2 << 4) & 0xf0) | (byte3 >> 2);\n output.push(outByte2);\n\n if (byte4 !== 64) {\n const outByte3 = ((byte3 << 6) & 0xc0) | byte4;\n output.push(outByte3);\n }\n }\n }\n\n return output;\n },\n\n /**\n * Lazy static initialization function. Called before\n * accessing any of the static map variables.\n * @private\n */\n init_() {\n if (!this.byteToCharMap_) {\n this.byteToCharMap_ = {};\n this.charToByteMap_ = {};\n this.byteToCharMapWebSafe_ = {};\n this.charToByteMapWebSafe_ = {};\n\n // We want quick mappings back and forth, so we precompute two maps.\n for (let i = 0; i < this.ENCODED_VALS.length; i++) {\n this.byteToCharMap_[i] = this.ENCODED_VALS.charAt(i);\n this.charToByteMap_[this.byteToCharMap_[i]] = i;\n this.byteToCharMapWebSafe_[i] = this.ENCODED_VALS_WEBSAFE.charAt(i);\n this.charToByteMapWebSafe_[this.byteToCharMapWebSafe_[i]] = i;\n\n // Be forgiving when decoding and correctly decode both encodings.\n if (i >= this.ENCODED_VALS_BASE.length) {\n this.charToByteMap_[this.ENCODED_VALS_WEBSAFE.charAt(i)] = i;\n this.charToByteMapWebSafe_[this.ENCODED_VALS.charAt(i)] = i;\n }\n }\n }\n }\n};\n\n/**\n * URL-safe base64 encoding\n */\nexport const base64Encode = function (str: string): string {\n const utf8Bytes = stringToByteArray(str);\n return base64.encodeByteArray(utf8Bytes, true);\n};\n\n/**\n * URL-safe base64 encoding (without \".\" padding in the end).\n * e.g. Used in JSON Web Token (JWT) parts.\n */\nexport const base64urlEncodeWithoutPadding = function (str: string): string {\n // Use base64url encoding and remove padding in the end (dot characters).\n return base64Encode(str).replace(/\\./g, '');\n};\n\n/**\n * URL-safe base64 decoding\n *\n * NOTE: DO NOT use the global atob() function - it does NOT support the\n * base64Url variant encoding.\n *\n * @param str To be decoded\n * @return Decoded result, if possible\n */\nexport const base64Decode = function (str: string): string | null {\n try {\n return base64.decodeString(str, true);\n } catch (e) {\n console.error('base64Decode failed: ', e);\n }\n return null;\n};\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Do a deep-copy of basic JavaScript Objects or Arrays.\n */\nexport function deepCopy(value: T): T {\n return deepExtend(undefined, value) as T;\n}\n\n/**\n * Copy properties from source to target (recursively allows extension\n * of Objects and Arrays). Scalar values in the target are over-written.\n * If target is undefined, an object of the appropriate type will be created\n * (and returned).\n *\n * We recursively copy all child properties of plain Objects in the source- so\n * that namespace- like dictionaries are merged.\n *\n * Note that the target can be a function, in which case the properties in\n * the source Object are copied onto it as static properties of the Function.\n *\n * Note: we don't merge __proto__ to prevent prototype pollution\n */\nexport function deepExtend(target: unknown, source: unknown): unknown {\n if (!(source instanceof Object)) {\n return source;\n }\n\n switch (source.constructor) {\n case Date:\n // Treat Dates like scalars; if the target date object had any child\n // properties - they will be lost!\n const dateValue = source as Date;\n return new Date(dateValue.getTime());\n\n case Object:\n if (target === undefined) {\n target = {};\n }\n break;\n case Array:\n // Always copy the array source and overwrite the target.\n target = [];\n break;\n\n default:\n // Not a plain Object - treat it as a scalar.\n return source;\n }\n\n for (const prop in source) {\n // use isValidKey to guard against prototype pollution. See https://snyk.io/vuln/SNYK-JS-LODASH-450202\n if (!source.hasOwnProperty(prop) || !isValidKey(prop)) {\n continue;\n }\n (target as Record)[prop] = deepExtend(\n (target as Record)[prop],\n (source as Record)[prop]\n );\n }\n\n return target;\n}\n\nfunction isValidKey(key: string): boolean {\n return key !== '__proto__';\n}\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport class Deferred {\n promise: Promise;\n reject: (value?: unknown) => void = () => {};\n resolve: (value?: unknown) => void = () => {};\n constructor() {\n this.promise = new Promise((resolve, reject) => {\n this.resolve = resolve as (value?: unknown) => void;\n this.reject = reject as (value?: unknown) => void;\n });\n }\n\n /**\n * Our API internals are not promiseified and cannot because our callback APIs have subtle expectations around\n * invoking promises inline, which Promises are forbidden to do. This method accepts an optional node-style callback\n * and returns a node-style callback which will resolve or reject the Deferred's promise.\n */\n wrapCallback(\n callback?: (error?: unknown, value?: unknown) => void\n ): (error: unknown, value?: unknown) => void {\n return (error, value?) => {\n if (error) {\n this.reject(error);\n } else {\n this.resolve(value);\n }\n if (typeof callback === 'function') {\n // Attaching noop handler just in case developer wasn't expecting\n // promises\n this.promise.catch(() => {});\n\n // Some of our callbacks don't expect a value and our own tests\n // assert that the parameter length is 1\n if (callback.length === 1) {\n callback(error);\n } else {\n callback(error, value);\n }\n }\n };\n }\n}\n", "/**\n * @license\n * Copyright 2021 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { base64urlEncodeWithoutPadding } from './crypt';\n\n// Firebase Auth tokens contain snake_case claims following the JWT standard / convention.\n/* eslint-disable camelcase */\n\nexport type FirebaseSignInProvider =\n | 'custom'\n | 'email'\n | 'password'\n | 'phone'\n | 'anonymous'\n | 'google.com'\n | 'facebook.com'\n | 'github.com'\n | 'twitter.com'\n | 'microsoft.com'\n | 'apple.com';\n\ninterface FirebaseIdToken {\n // Always set to https://securetoken.google.com/PROJECT_ID\n iss: string;\n\n // Always set to PROJECT_ID\n aud: string;\n\n // The user's unique ID\n sub: string;\n\n // The token issue time, in seconds since epoch\n iat: number;\n\n // The token expiry time, normally 'iat' + 3600\n exp: number;\n\n // The user's unique ID. Must be equal to 'sub'\n user_id: string;\n\n // The time the user authenticated, normally 'iat'\n auth_time: number;\n\n // The sign in provider, only set when the provider is 'anonymous'\n provider_id?: 'anonymous';\n\n // The user's primary email\n email?: string;\n\n // The user's email verification status\n email_verified?: boolean;\n\n // The user's primary phone number\n phone_number?: string;\n\n // The user's display name\n name?: string;\n\n // The user's profile photo URL\n picture?: string;\n\n // Information on all identities linked to this user\n firebase: {\n // The primary sign-in provider\n sign_in_provider: FirebaseSignInProvider;\n\n // A map of providers to the user's list of unique identifiers from\n // each provider\n identities?: { [provider in FirebaseSignInProvider]?: string[] };\n };\n\n // Custom claims set by the developer\n [claim: string]: unknown;\n\n uid?: never; // Try to catch a common mistake of \"uid\" (should be \"sub\" instead).\n}\n\nexport type EmulatorMockTokenOptions = ({ user_id: string } | { sub: string }) &\n Partial;\n\nexport function createMockUserToken(\n token: EmulatorMockTokenOptions,\n projectId?: string\n): string {\n if (token.uid) {\n throw new Error(\n 'The \"uid\" field is no longer supported by mockUserToken. Please use \"sub\" instead for Firebase Auth User ID.'\n );\n }\n // Unsecured JWTs use \"none\" as the algorithm.\n const header = {\n alg: 'none',\n type: 'JWT'\n };\n\n const project = projectId || 'demo-project';\n const iat = token.iat || 0;\n const sub = token.sub || token.user_id;\n if (!sub) {\n throw new Error(\"mockUserToken must contain 'sub' or 'user_id' field!\");\n }\n\n const payload: FirebaseIdToken = {\n // Set all required fields to decent defaults\n iss: `https://securetoken.google.com/${project}`,\n aud: project,\n iat,\n exp: iat + 3600,\n auth_time: iat,\n sub,\n user_id: sub,\n firebase: {\n sign_in_provider: 'custom',\n identities: {}\n },\n\n // Override with user options\n ...token\n };\n\n // Unsecured JWTs use the empty string as a signature.\n const signature = '';\n return [\n base64urlEncodeWithoutPadding(JSON.stringify(header)),\n base64urlEncodeWithoutPadding(JSON.stringify(payload)),\n signature\n ].join('.');\n}\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { CONSTANTS } from './constants';\n\n/**\n * Returns navigator.userAgent string or '' if it's not defined.\n * @return user agent string\n */\nexport function getUA(): string {\n if (\n typeof navigator !== 'undefined' &&\n typeof navigator['userAgent'] === 'string'\n ) {\n return navigator['userAgent'];\n } else {\n return '';\n }\n}\n\n/**\n * Detect Cordova / PhoneGap / Ionic frameworks on a mobile device.\n *\n * Deliberately does not rely on checking `file://` URLs (as this fails PhoneGap\n * in the Ripple emulator) nor Cordova `onDeviceReady`, which would normally\n * wait for a callback.\n */\nexport function isMobileCordova(): boolean {\n return (\n typeof window !== 'undefined' &&\n // @ts-ignore Setting up an broadly applicable index signature for Window\n // just to deal with this case would probably be a bad idea.\n !!(window['cordova'] || window['phonegap'] || window['PhoneGap']) &&\n /ios|iphone|ipod|ipad|android|blackberry|iemobile/i.test(getUA())\n );\n}\n\n/**\n * Detect Node.js.\n *\n * @return true if Node.js environment is detected.\n */\n// Node detection logic from: https://github.com/iliakan/detect-node/\nexport function isNode(): boolean {\n try {\n return (\n Object.prototype.toString.call(global.process) === '[object process]'\n );\n } catch (e) {\n return false;\n }\n}\n\n/**\n * Detect Browser Environment\n */\nexport function isBrowser(): boolean {\n return typeof self === 'object' && self.self === self;\n}\n\n/**\n * Detect browser extensions (Chrome and Firefox at least).\n */\ninterface BrowserRuntime {\n id?: unknown;\n}\ndeclare const chrome: { runtime?: BrowserRuntime };\ndeclare const browser: { runtime?: BrowserRuntime };\nexport function isBrowserExtension(): boolean {\n const runtime =\n typeof chrome === 'object'\n ? chrome.runtime\n : typeof browser === 'object'\n ? browser.runtime\n : undefined;\n return typeof runtime === 'object' && runtime.id !== undefined;\n}\n\n/**\n * Detect React Native.\n *\n * @return true if ReactNative environment is detected.\n */\nexport function isReactNative(): boolean {\n return (\n typeof navigator === 'object' && navigator['product'] === 'ReactNative'\n );\n}\n\n/** Detects Electron apps. */\nexport function isElectron(): boolean {\n return getUA().indexOf('Electron/') >= 0;\n}\n\n/** Detects Internet Explorer. */\nexport function isIE(): boolean {\n const ua = getUA();\n return ua.indexOf('MSIE ') >= 0 || ua.indexOf('Trident/') >= 0;\n}\n\n/** Detects Universal Windows Platform apps. */\nexport function isUWP(): boolean {\n return getUA().indexOf('MSAppHost/') >= 0;\n}\n\n/**\n * Detect whether the current SDK build is the Node version.\n *\n * @return true if it's the Node SDK build.\n */\nexport function isNodeSdk(): boolean {\n return CONSTANTS.NODE_CLIENT === true || CONSTANTS.NODE_ADMIN === true;\n}\n\n/** Returns true if we are running in Safari. */\nexport function isSafari(): boolean {\n return (\n !isNode() &&\n navigator.userAgent.includes('Safari') &&\n !navigator.userAgent.includes('Chrome')\n );\n}\n\n/**\n * This method checks if indexedDB is supported by current browser/service worker context\n * @return true if indexedDB is supported by current browser/service worker context\n */\nexport function isIndexedDBAvailable(): boolean {\n return typeof indexedDB === 'object';\n}\n\n/**\n * This method validates browser/sw context for indexedDB by opening a dummy indexedDB database and reject\n * if errors occur during the database open operation.\n *\n * @throws exception if current browser/sw context can't run idb.open (ex: Safari iframe, Firefox\n * private browsing)\n */\nexport function validateIndexedDBOpenable(): Promise {\n return new Promise((resolve, reject) => {\n try {\n let preExist: boolean = true;\n const DB_CHECK_NAME =\n 'validate-browser-context-for-indexeddb-analytics-module';\n const request = self.indexedDB.open(DB_CHECK_NAME);\n request.onsuccess = () => {\n request.result.close();\n // delete database only when it doesn't pre-exist\n if (!preExist) {\n self.indexedDB.deleteDatabase(DB_CHECK_NAME);\n }\n resolve(true);\n };\n request.onupgradeneeded = () => {\n preExist = false;\n };\n\n request.onerror = () => {\n reject(request.error?.message || '');\n };\n } catch (error) {\n reject(error);\n }\n });\n}\n\n/**\n *\n * This method checks whether cookie is enabled within current browser\n * @return true if cookie is enabled within current browser\n */\nexport function areCookiesEnabled(): boolean {\n if (typeof navigator === 'undefined' || !navigator.cookieEnabled) {\n return false;\n }\n return true;\n}\n\n/**\n * Polyfill for `globalThis` object.\n * @returns the `globalThis` object for the given environment.\n */\nexport function getGlobal(): typeof globalThis {\n if (typeof self !== 'undefined') {\n return self;\n }\n if (typeof window !== 'undefined') {\n return window;\n }\n if (typeof global !== 'undefined') {\n return global;\n }\n throw new Error('Unable to locate global object.');\n}\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/**\n * @fileoverview Standardized Firebase Error.\n *\n * Usage:\n *\n * // Typescript string literals for type-safe codes\n * type Err =\n * 'unknown' |\n * 'object-not-found'\n * ;\n *\n * // Closure enum for type-safe error codes\n * // at-enum {string}\n * var Err = {\n * UNKNOWN: 'unknown',\n * OBJECT_NOT_FOUND: 'object-not-found',\n * }\n *\n * let errors: Map = {\n * 'generic-error': \"Unknown error\",\n * 'file-not-found': \"Could not find file: {$file}\",\n * };\n *\n * // Type-safe function - must pass a valid error code as param.\n * let error = new ErrorFactory('service', 'Service', errors);\n *\n * ...\n * throw error.create(Err.GENERIC);\n * ...\n * throw error.create(Err.FILE_NOT_FOUND, {'file': fileName});\n * ...\n * // Service: Could not file file: foo.txt (service/file-not-found).\n *\n * catch (e) {\n * assert(e.message === \"Could not find file: foo.txt.\");\n * if ((e as FirebaseError)?.code === 'service/file-not-found') {\n * console.log(\"Could not read file: \" + e['file']);\n * }\n * }\n */\n\nexport type ErrorMap = {\n readonly [K in ErrorCode]: string;\n};\n\nconst ERROR_NAME = 'FirebaseError';\n\nexport interface StringLike {\n toString(): string;\n}\n\nexport interface ErrorData {\n [key: string]: unknown;\n}\n\n// Based on code from:\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error#Custom_Error_Types\nexport class FirebaseError extends Error {\n /** The custom name for all FirebaseErrors. */\n readonly name: string = ERROR_NAME;\n\n constructor(\n /** The error code for this error. */\n readonly code: string,\n message: string,\n /** Custom data for this error. */\n public customData?: Record\n ) {\n super(message);\n\n // Fix For ES5\n // https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work\n Object.setPrototypeOf(this, FirebaseError.prototype);\n\n // Maintains proper stack trace for where our error was thrown.\n // Only available on V8.\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, ErrorFactory.prototype.create);\n }\n }\n}\n\nexport class ErrorFactory<\n ErrorCode extends string,\n ErrorParams extends { readonly [K in ErrorCode]?: ErrorData } = {}\n> {\n constructor(\n private readonly service: string,\n private readonly serviceName: string,\n private readonly errors: ErrorMap\n ) {}\n\n create(\n code: K,\n ...data: K extends keyof ErrorParams ? [ErrorParams[K]] : []\n ): FirebaseError {\n const customData = (data[0] as ErrorData) || {};\n const fullCode = `${this.service}/${code}`;\n const template = this.errors[code];\n\n const message = template ? replaceTemplate(template, customData) : 'Error';\n // Service Name: Error message (service/code).\n const fullMessage = `${this.serviceName}: ${message} (${fullCode}).`;\n\n const error = new FirebaseError(fullCode, fullMessage, customData);\n\n return error;\n }\n}\n\nfunction replaceTemplate(template: string, data: ErrorData): string {\n return template.replace(PATTERN, (_, key) => {\n const value = data[key];\n return value != null ? String(value) : `<${key}?>`;\n });\n}\n\nconst PATTERN = /\\{\\$([^}]+)}/g;\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Evaluates a JSON string into a javascript object.\n *\n * @param {string} str A string containing JSON.\n * @return {*} The javascript object representing the specified JSON.\n */\nexport function jsonEval(str: string): unknown {\n return JSON.parse(str);\n}\n\n/**\n * Returns JSON representing a javascript object.\n * @param {*} data Javascript object to be stringified.\n * @return {string} The JSON contents of the object.\n */\nexport function stringify(data: unknown): string {\n return JSON.stringify(data);\n}\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { base64Decode } from './crypt';\nimport { jsonEval } from './json';\n\ninterface Claims {\n [key: string]: {};\n}\n\ninterface DecodedToken {\n header: object;\n claims: Claims;\n data: object;\n signature: string;\n}\n\n/**\n * Decodes a Firebase auth. token into constituent parts.\n *\n * Notes:\n * - May return with invalid / incomplete claims if there's no native base64 decoding support.\n * - Doesn't check if the token is actually valid.\n */\nexport const decode = function (token: string): DecodedToken {\n let header = {},\n claims: Claims = {},\n data = {},\n signature = '';\n\n try {\n const parts = token.split('.');\n header = jsonEval(base64Decode(parts[0]) || '') as object;\n claims = jsonEval(base64Decode(parts[1]) || '') as Claims;\n signature = parts[2];\n data = claims['d'] || {};\n delete claims['d'];\n } catch (e) {}\n\n return {\n header,\n claims,\n data,\n signature\n };\n};\n\ninterface DecodedToken {\n header: object;\n claims: Claims;\n data: object;\n signature: string;\n}\n\n/**\n * Decodes a Firebase auth. token and checks the validity of its time-based claims. Will return true if the\n * token is within the time window authorized by the 'nbf' (not-before) and 'iat' (issued-at) claims.\n *\n * Notes:\n * - May return a false negative if there's no native base64 decoding support.\n * - Doesn't check if the token is actually valid.\n */\nexport const isValidTimestamp = function (token: string): boolean {\n const claims: Claims = decode(token).claims;\n const now: number = Math.floor(new Date().getTime() / 1000);\n let validSince: number = 0,\n validUntil: number = 0;\n\n if (typeof claims === 'object') {\n if (claims.hasOwnProperty('nbf')) {\n validSince = claims['nbf'] as number;\n } else if (claims.hasOwnProperty('iat')) {\n validSince = claims['iat'] as number;\n }\n\n if (claims.hasOwnProperty('exp')) {\n validUntil = claims['exp'] as number;\n } else {\n // token will expire after 24h by default\n validUntil = validSince + 86400;\n }\n }\n\n return (\n !!now &&\n !!validSince &&\n !!validUntil &&\n now >= validSince &&\n now <= validUntil\n );\n};\n\n/**\n * Decodes a Firebase auth. token and returns its issued at time if valid, null otherwise.\n *\n * Notes:\n * - May return null if there's no native base64 decoding support.\n * - Doesn't check if the token is actually valid.\n */\nexport const issuedAtTime = function (token: string): number | null {\n const claims: Claims = decode(token).claims;\n if (typeof claims === 'object' && claims.hasOwnProperty('iat')) {\n return claims['iat'] as number;\n }\n return null;\n};\n\n/**\n * Decodes a Firebase auth. token and checks the validity of its format. Expects a valid issued-at time.\n *\n * Notes:\n * - May return a false negative if there's no native base64 decoding support.\n * - Doesn't check if the token is actually valid.\n */\nexport const isValidFormat = function (token: string): boolean {\n const decoded = decode(token),\n claims = decoded.claims;\n\n return !!claims && typeof claims === 'object' && claims.hasOwnProperty('iat');\n};\n\n/**\n * Attempts to peer into an auth token and determine if it's an admin auth token by looking at the claims portion.\n *\n * Notes:\n * - May return a false negative if there's no native base64 decoding support.\n * - Doesn't check if the token is actually valid.\n */\nexport const isAdmin = function (token: string): boolean {\n const claims: Claims = decode(token).claims;\n return typeof claims === 'object' && claims['admin'] === true;\n};\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport function contains(obj: T, key: string): boolean {\n return Object.prototype.hasOwnProperty.call(obj, key);\n}\n\nexport function safeGet(\n obj: T,\n key: K\n): T[K] | undefined {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n return obj[key];\n } else {\n return undefined;\n }\n}\n\nexport function isEmpty(obj: object): obj is {} {\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n return false;\n }\n }\n return true;\n}\n\nexport function map(\n obj: { [key in K]: V },\n fn: (value: V, key: K, obj: { [key in K]: V }) => U,\n contextObj?: unknown\n): { [key in K]: U } {\n const res: Partial<{ [key in K]: U }> = {};\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n res[key] = fn.call(contextObj, obj[key], key, obj);\n }\n }\n return res as { [key in K]: U };\n}\n\n/**\n * Deep equal two objects. Support Arrays and Objects.\n */\nexport function deepEqual(a: object, b: object): boolean {\n if (a === b) {\n return true;\n }\n\n const aKeys = Object.keys(a);\n const bKeys = Object.keys(b);\n for (const k of aKeys) {\n if (!bKeys.includes(k)) {\n return false;\n }\n\n const aProp = (a as Record)[k];\n const bProp = (b as Record)[k];\n if (isObject(aProp) && isObject(bProp)) {\n if (!deepEqual(aProp, bProp)) {\n return false;\n }\n } else if (aProp !== bProp) {\n return false;\n }\n }\n\n for (const k of bKeys) {\n if (!aKeys.includes(k)) {\n return false;\n }\n }\n return true;\n}\n\nfunction isObject(thing: unknown): thing is object {\n return thing !== null && typeof thing === 'object';\n}\n", "/**\n * @license\n * Copyright 2022 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Deferred } from './deferred';\n\n/**\n * Rejects if the given promise doesn't resolve in timeInMS milliseconds.\n * @internal\n */\nexport function promiseWithTimeout(\n promise: Promise,\n timeInMS = 2000\n): Promise {\n const deferredPromise = new Deferred();\n setTimeout(() => deferredPromise.reject('timeout!'), timeInMS);\n promise.then(deferredPromise.resolve, deferredPromise.reject);\n return deferredPromise.promise;\n}\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Returns a querystring-formatted string (e.g. &arg=val&arg2=val2) from a\n * params object (e.g. {arg: 'val', arg2: 'val2'})\n * Note: You must prepend it with ? when adding it to a URL.\n */\nexport function querystring(querystringParams: {\n [key: string]: string | number;\n}): string {\n const params = [];\n for (const [key, value] of Object.entries(querystringParams)) {\n if (Array.isArray(value)) {\n value.forEach(arrayVal => {\n params.push(\n encodeURIComponent(key) + '=' + encodeURIComponent(arrayVal)\n );\n });\n } else {\n params.push(encodeURIComponent(key) + '=' + encodeURIComponent(value));\n }\n }\n return params.length ? '&' + params.join('&') : '';\n}\n\n/**\n * Decodes a querystring (e.g. ?arg=val&arg2=val2) into a params object\n * (e.g. {arg: 'val', arg2: 'val2'})\n */\nexport function querystringDecode(querystring: string): Record {\n const obj: Record = {};\n const tokens = querystring.replace(/^\\?/, '').split('&');\n\n tokens.forEach(token => {\n if (token) {\n const [key, value] = token.split('=');\n obj[decodeURIComponent(key)] = decodeURIComponent(value);\n }\n });\n return obj;\n}\n\n/**\n * Extract the query string part of a URL, including the leading question mark (if present).\n */\nexport function extractQuerystring(url: string): string {\n const queryStart = url.indexOf('?');\n if (!queryStart) {\n return '';\n }\n const fragmentStart = url.indexOf('#', queryStart);\n return url.substring(\n queryStart,\n fragmentStart > 0 ? fragmentStart : undefined\n );\n}\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * @fileoverview SHA-1 cryptographic hash.\n * Variable names follow the notation in FIPS PUB 180-3:\n * http://csrc.nist.gov/publications/fips/fips180-3/fips180-3_final.pdf.\n *\n * Usage:\n * var sha1 = new sha1();\n * sha1.update(bytes);\n * var hash = sha1.digest();\n *\n * Performance:\n * Chrome 23: ~400 Mbit/s\n * Firefox 16: ~250 Mbit/s\n *\n */\n\n/**\n * SHA-1 cryptographic hash constructor.\n *\n * The properties declared here are discussed in the above algorithm document.\n * @constructor\n * @final\n * @struct\n */\nexport class Sha1 {\n /**\n * Holds the previous values of accumulated variables a-e in the compress_\n * function.\n * @private\n */\n private chain_: number[] = [];\n\n /**\n * A buffer holding the partially computed hash result.\n * @private\n */\n private buf_: number[] = [];\n\n /**\n * An array of 80 bytes, each a part of the message to be hashed. Referred to\n * as the message schedule in the docs.\n * @private\n */\n private W_: number[] = [];\n\n /**\n * Contains data needed to pad messages less than 64 bytes.\n * @private\n */\n private pad_: number[] = [];\n\n /**\n * @private {number}\n */\n private inbuf_: number = 0;\n\n /**\n * @private {number}\n */\n private total_: number = 0;\n\n blockSize: number;\n\n constructor() {\n this.blockSize = 512 / 8;\n\n this.pad_[0] = 128;\n for (let i = 1; i < this.blockSize; ++i) {\n this.pad_[i] = 0;\n }\n\n this.reset();\n }\n\n reset(): void {\n this.chain_[0] = 0x67452301;\n this.chain_[1] = 0xefcdab89;\n this.chain_[2] = 0x98badcfe;\n this.chain_[3] = 0x10325476;\n this.chain_[4] = 0xc3d2e1f0;\n\n this.inbuf_ = 0;\n this.total_ = 0;\n }\n\n /**\n * Internal compress helper function.\n * @param buf Block to compress.\n * @param offset Offset of the block in the buffer.\n * @private\n */\n compress_(buf: number[] | Uint8Array | string, offset?: number): void {\n if (!offset) {\n offset = 0;\n }\n\n const W = this.W_;\n\n // get 16 big endian words\n if (typeof buf === 'string') {\n for (let i = 0; i < 16; i++) {\n // TODO(user): [bug 8140122] Recent versions of Safari for Mac OS and iOS\n // have a bug that turns the post-increment ++ operator into pre-increment\n // during JIT compilation. We have code that depends heavily on SHA-1 for\n // correctness and which is affected by this bug, so I've removed all uses\n // of post-increment ++ in which the result value is used. We can revert\n // this change once the Safari bug\n // (https://bugs.webkit.org/show_bug.cgi?id=109036) has been fixed and\n // most clients have been updated.\n W[i] =\n (buf.charCodeAt(offset) << 24) |\n (buf.charCodeAt(offset + 1) << 16) |\n (buf.charCodeAt(offset + 2) << 8) |\n buf.charCodeAt(offset + 3);\n offset += 4;\n }\n } else {\n for (let i = 0; i < 16; i++) {\n W[i] =\n (buf[offset] << 24) |\n (buf[offset + 1] << 16) |\n (buf[offset + 2] << 8) |\n buf[offset + 3];\n offset += 4;\n }\n }\n\n // expand to 80 words\n for (let i = 16; i < 80; i++) {\n const t = W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16];\n W[i] = ((t << 1) | (t >>> 31)) & 0xffffffff;\n }\n\n let a = this.chain_[0];\n let b = this.chain_[1];\n let c = this.chain_[2];\n let d = this.chain_[3];\n let e = this.chain_[4];\n let f, k;\n\n // TODO(user): Try to unroll this loop to speed up the computation.\n for (let i = 0; i < 80; i++) {\n if (i < 40) {\n if (i < 20) {\n f = d ^ (b & (c ^ d));\n k = 0x5a827999;\n } else {\n f = b ^ c ^ d;\n k = 0x6ed9eba1;\n }\n } else {\n if (i < 60) {\n f = (b & c) | (d & (b | c));\n k = 0x8f1bbcdc;\n } else {\n f = b ^ c ^ d;\n k = 0xca62c1d6;\n }\n }\n\n const t = (((a << 5) | (a >>> 27)) + f + e + k + W[i]) & 0xffffffff;\n e = d;\n d = c;\n c = ((b << 30) | (b >>> 2)) & 0xffffffff;\n b = a;\n a = t;\n }\n\n this.chain_[0] = (this.chain_[0] + a) & 0xffffffff;\n this.chain_[1] = (this.chain_[1] + b) & 0xffffffff;\n this.chain_[2] = (this.chain_[2] + c) & 0xffffffff;\n this.chain_[3] = (this.chain_[3] + d) & 0xffffffff;\n this.chain_[4] = (this.chain_[4] + e) & 0xffffffff;\n }\n\n update(bytes?: number[] | Uint8Array | string, length?: number): void {\n // TODO(johnlenz): tighten the function signature and remove this check\n if (bytes == null) {\n return;\n }\n\n if (length === undefined) {\n length = bytes.length;\n }\n\n const lengthMinusBlock = length - this.blockSize;\n let n = 0;\n // Using local instead of member variables gives ~5% speedup on Firefox 16.\n const buf = this.buf_;\n let inbuf = this.inbuf_;\n\n // The outer while loop should execute at most twice.\n while (n < length) {\n // When we have no data in the block to top up, we can directly process the\n // input buffer (assuming it contains sufficient data). This gives ~25%\n // speedup on Chrome 23 and ~15% speedup on Firefox 16, but requires that\n // the data is provided in large chunks (or in multiples of 64 bytes).\n if (inbuf === 0) {\n while (n <= lengthMinusBlock) {\n this.compress_(bytes, n);\n n += this.blockSize;\n }\n }\n\n if (typeof bytes === 'string') {\n while (n < length) {\n buf[inbuf] = bytes.charCodeAt(n);\n ++inbuf;\n ++n;\n if (inbuf === this.blockSize) {\n this.compress_(buf);\n inbuf = 0;\n // Jump to the outer loop so we use the full-block optimization.\n break;\n }\n }\n } else {\n while (n < length) {\n buf[inbuf] = bytes[n];\n ++inbuf;\n ++n;\n if (inbuf === this.blockSize) {\n this.compress_(buf);\n inbuf = 0;\n // Jump to the outer loop so we use the full-block optimization.\n break;\n }\n }\n }\n }\n\n this.inbuf_ = inbuf;\n this.total_ += length;\n }\n\n /** @override */\n digest(): number[] {\n const digest: number[] = [];\n let totalBits = this.total_ * 8;\n\n // Add pad 0x80 0x00*.\n if (this.inbuf_ < 56) {\n this.update(this.pad_, 56 - this.inbuf_);\n } else {\n this.update(this.pad_, this.blockSize - (this.inbuf_ - 56));\n }\n\n // Add # bits.\n for (let i = this.blockSize - 1; i >= 56; i--) {\n this.buf_[i] = totalBits & 255;\n totalBits /= 256; // Don't use bit-shifting here!\n }\n\n this.compress_(this.buf_);\n\n let n = 0;\n for (let i = 0; i < 5; i++) {\n for (let j = 24; j >= 0; j -= 8) {\n digest[n] = (this.chain_[i] >> j) & 255;\n ++n;\n }\n }\n return digest;\n }\n}\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nexport type NextFn = (value: T) => void;\nexport type ErrorFn = (error: Error) => void;\nexport type CompleteFn = () => void;\n\nexport interface Observer {\n // Called once for each value in a stream of values.\n next: NextFn;\n\n // A stream terminates by a single call to EITHER error() or complete().\n error: ErrorFn;\n\n // No events will be sent to next() once complete() is called.\n complete: CompleteFn;\n}\n\nexport type PartialObserver = Partial>;\n\n// TODO: Support also Unsubscribe.unsubscribe?\nexport type Unsubscribe = () => void;\n\n/**\n * The Subscribe interface has two forms - passing the inline function\n * callbacks, or a object interface with callback properties.\n */\nexport interface Subscribe {\n (next?: NextFn, error?: ErrorFn, complete?: CompleteFn): Unsubscribe;\n (observer: PartialObserver): Unsubscribe;\n}\n\nexport interface Observable {\n // Subscribe method\n subscribe: Subscribe;\n}\n\nexport type Executor = (observer: Observer) => void;\n\n/**\n * Helper to make a Subscribe function (just like Promise helps make a\n * Thenable).\n *\n * @param executor Function which can make calls to a single Observer\n * as a proxy.\n * @param onNoObservers Callback when count of Observers goes to zero.\n */\nexport function createSubscribe(\n executor: Executor,\n onNoObservers?: Executor\n): Subscribe {\n const proxy = new ObserverProxy(executor, onNoObservers);\n return proxy.subscribe.bind(proxy);\n}\n\n/**\n * Implement fan-out for any number of Observers attached via a subscribe\n * function.\n */\nclass ObserverProxy implements Observer {\n private observers: Array> | undefined = [];\n private unsubscribes: Unsubscribe[] = [];\n private onNoObservers: Executor | undefined;\n private observerCount = 0;\n // Micro-task scheduling by calling task.then().\n private task = Promise.resolve();\n private finalized = false;\n private finalError?: Error;\n\n /**\n * @param executor Function which can make calls to a single Observer\n * as a proxy.\n * @param onNoObservers Callback when count of Observers goes to zero.\n */\n constructor(executor: Executor, onNoObservers?: Executor) {\n this.onNoObservers = onNoObservers;\n // Call the executor asynchronously so subscribers that are called\n // synchronously after the creation of the subscribe function\n // can still receive the very first value generated in the executor.\n this.task\n .then(() => {\n executor(this);\n })\n .catch(e => {\n this.error(e);\n });\n }\n\n next(value: T): void {\n this.forEachObserver((observer: Observer) => {\n observer.next(value);\n });\n }\n\n error(error: Error): void {\n this.forEachObserver((observer: Observer) => {\n observer.error(error);\n });\n this.close(error);\n }\n\n complete(): void {\n this.forEachObserver((observer: Observer) => {\n observer.complete();\n });\n this.close();\n }\n\n /**\n * Subscribe function that can be used to add an Observer to the fan-out list.\n *\n * - We require that no event is sent to a subscriber sychronously to their\n * call to subscribe().\n */\n subscribe(\n nextOrObserver?: NextFn | PartialObserver,\n error?: ErrorFn,\n complete?: CompleteFn\n ): Unsubscribe {\n let observer: Observer;\n\n if (\n nextOrObserver === undefined &&\n error === undefined &&\n complete === undefined\n ) {\n throw new Error('Missing Observer.');\n }\n\n // Assemble an Observer object when passed as callback functions.\n if (\n implementsAnyMethods(nextOrObserver as { [key: string]: unknown }, [\n 'next',\n 'error',\n 'complete'\n ])\n ) {\n observer = nextOrObserver as Observer;\n } else {\n observer = {\n next: nextOrObserver as NextFn,\n error,\n complete\n } as Observer;\n }\n\n if (observer.next === undefined) {\n observer.next = noop as NextFn;\n }\n if (observer.error === undefined) {\n observer.error = noop as ErrorFn;\n }\n if (observer.complete === undefined) {\n observer.complete = noop as CompleteFn;\n }\n\n const unsub = this.unsubscribeOne.bind(this, this.observers!.length);\n\n // Attempt to subscribe to a terminated Observable - we\n // just respond to the Observer with the final error or complete\n // event.\n if (this.finalized) {\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.task.then(() => {\n try {\n if (this.finalError) {\n observer.error(this.finalError);\n } else {\n observer.complete();\n }\n } catch (e) {\n // nothing\n }\n return;\n });\n }\n\n this.observers!.push(observer as Observer);\n\n return unsub;\n }\n\n // Unsubscribe is synchronous - we guarantee that no events are sent to\n // any unsubscribed Observer.\n private unsubscribeOne(i: number): void {\n if (this.observers === undefined || this.observers[i] === undefined) {\n return;\n }\n\n delete this.observers[i];\n\n this.observerCount -= 1;\n if (this.observerCount === 0 && this.onNoObservers !== undefined) {\n this.onNoObservers(this);\n }\n }\n\n private forEachObserver(fn: (observer: Observer) => void): void {\n if (this.finalized) {\n // Already closed by previous event....just eat the additional values.\n return;\n }\n\n // Since sendOne calls asynchronously - there is no chance that\n // this.observers will become undefined.\n for (let i = 0; i < this.observers!.length; i++) {\n this.sendOne(i, fn);\n }\n }\n\n // Call the Observer via one of it's callback function. We are careful to\n // confirm that the observe has not been unsubscribed since this asynchronous\n // function had been queued.\n private sendOne(i: number, fn: (observer: Observer) => void): void {\n // Execute the callback asynchronously\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.task.then(() => {\n if (this.observers !== undefined && this.observers[i] !== undefined) {\n try {\n fn(this.observers[i]);\n } catch (e) {\n // Ignore exceptions raised in Observers or missing methods of an\n // Observer.\n // Log error to console. b/31404806\n if (typeof console !== 'undefined' && console.error) {\n console.error(e);\n }\n }\n }\n });\n }\n\n private close(err?: Error): void {\n if (this.finalized) {\n return;\n }\n this.finalized = true;\n if (err !== undefined) {\n this.finalError = err;\n }\n // Proxy is no longer needed - garbage collect references\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.task.then(() => {\n this.observers = undefined;\n this.onNoObservers = undefined;\n });\n }\n}\n\n/** Turn synchronous function into one called asynchronously. */\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport function async(fn: Function, onError?: ErrorFn): Function {\n return (...args: unknown[]) => {\n Promise.resolve(true)\n .then(() => {\n fn(...args);\n })\n .catch((error: Error) => {\n if (onError) {\n onError(error);\n }\n });\n };\n}\n\n/**\n * Return true if the object passed in implements any of the named methods.\n */\nfunction implementsAnyMethods(\n obj: { [key: string]: unknown },\n methods: string[]\n): boolean {\n if (typeof obj !== 'object' || obj === null) {\n return false;\n }\n\n for (const method of methods) {\n if (method in obj && typeof obj[method] === 'function') {\n return true;\n }\n }\n\n return false;\n}\n\nfunction noop(): void {\n // do nothing\n}\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Check to make sure the appropriate number of arguments are provided for a public function.\n * Throws an error if it fails.\n *\n * @param fnName The function name\n * @param minCount The minimum number of arguments to allow for the function call\n * @param maxCount The maximum number of argument to allow for the function call\n * @param argCount The actual number of arguments provided.\n */\nexport const validateArgCount = function (\n fnName: string,\n minCount: number,\n maxCount: number,\n argCount: number\n): void {\n let argError;\n if (argCount < minCount) {\n argError = 'at least ' + minCount;\n } else if (argCount > maxCount) {\n argError = maxCount === 0 ? 'none' : 'no more than ' + maxCount;\n }\n if (argError) {\n const error =\n fnName +\n ' failed: Was called with ' +\n argCount +\n (argCount === 1 ? ' argument.' : ' arguments.') +\n ' Expects ' +\n argError +\n '.';\n throw new Error(error);\n }\n};\n\n/**\n * Generates a string to prefix an error message about failed argument validation\n *\n * @param fnName The function name\n * @param argName The name of the argument\n * @return The prefix to add to the error thrown for validation.\n */\nexport function errorPrefix(fnName: string, argName: string): string {\n return `${fnName} failed: ${argName} argument `;\n}\n\n/**\n * @param fnName\n * @param argumentNumber\n * @param namespace\n * @param optional\n */\nexport function validateNamespace(\n fnName: string,\n namespace: string,\n optional: boolean\n): void {\n if (optional && !namespace) {\n return;\n }\n if (typeof namespace !== 'string') {\n //TODO: I should do more validation here. We only allow certain chars in namespaces.\n throw new Error(\n errorPrefix(fnName, 'namespace') + 'must be a valid firebase namespace.'\n );\n }\n}\n\nexport function validateCallback(\n fnName: string,\n argumentName: string,\n // eslint-disable-next-line @typescript-eslint/ban-types\n callback: Function,\n optional: boolean\n): void {\n if (optional && !callback) {\n return;\n }\n if (typeof callback !== 'function') {\n throw new Error(\n errorPrefix(fnName, argumentName) + 'must be a valid function.'\n );\n }\n}\n\nexport function validateContextObject(\n fnName: string,\n argumentName: string,\n context: unknown,\n optional: boolean\n): void {\n if (optional && !context) {\n return;\n }\n if (typeof context !== 'object' || context === null) {\n throw new Error(\n errorPrefix(fnName, argumentName) + 'must be a valid context object.'\n );\n }\n}\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { assert } from './assert';\n\n// Code originally came from goog.crypt.stringToUtf8ByteArray, but for some reason they\n// automatically replaced '\\r\\n' with '\\n', and they didn't handle surrogate pairs,\n// so it's been modified.\n\n// Note that not all Unicode characters appear as single characters in JavaScript strings.\n// fromCharCode returns the UTF-16 encoding of a character - so some Unicode characters\n// use 2 characters in Javascript. All 4-byte UTF-8 characters begin with a first\n// character in the range 0xD800 - 0xDBFF (the first character of a so-called surrogate\n// pair).\n// See http://www.ecma-international.org/ecma-262/5.1/#sec-15.1.3\n\n/**\n * @param {string} str\n * @return {Array}\n */\nexport const stringToByteArray = function (str: string): number[] {\n const out: number[] = [];\n let p = 0;\n for (let i = 0; i < str.length; i++) {\n let c = str.charCodeAt(i);\n\n // Is this the lead surrogate in a surrogate pair?\n if (c >= 0xd800 && c <= 0xdbff) {\n const high = c - 0xd800; // the high 10 bits.\n i++;\n assert(i < str.length, 'Surrogate pair missing trail surrogate.');\n const low = str.charCodeAt(i) - 0xdc00; // the low 10 bits.\n c = 0x10000 + (high << 10) + low;\n }\n\n if (c < 128) {\n out[p++] = c;\n } else if (c < 2048) {\n out[p++] = (c >> 6) | 192;\n out[p++] = (c & 63) | 128;\n } else if (c < 65536) {\n out[p++] = (c >> 12) | 224;\n out[p++] = ((c >> 6) & 63) | 128;\n out[p++] = (c & 63) | 128;\n } else {\n out[p++] = (c >> 18) | 240;\n out[p++] = ((c >> 12) & 63) | 128;\n out[p++] = ((c >> 6) & 63) | 128;\n out[p++] = (c & 63) | 128;\n }\n }\n return out;\n};\n\n/**\n * Calculate length without actually converting; useful for doing cheaper validation.\n * @param {string} str\n * @return {number}\n */\nexport const stringLength = function (str: string): number {\n let p = 0;\n for (let i = 0; i < str.length; i++) {\n const c = str.charCodeAt(i);\n if (c < 128) {\n p++;\n } else if (c < 2048) {\n p += 2;\n } else if (c >= 0xd800 && c <= 0xdbff) {\n // Lead surrogate of a surrogate pair. The pair together will take 4 bytes to represent.\n p += 4;\n i++; // skip trail surrogate.\n } else {\n p += 3;\n }\n }\n return p;\n};\n", "/**\n * @license\n * Copyright 2022 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Copied from https://stackoverflow.com/a/2117523\n * Generates a new uuid.\n * @public\n */\nexport const uuidv4 = function (): string {\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {\n const r = (Math.random() * 16) | 0,\n v = c === 'x' ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n};\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * The amount of milliseconds to exponentially increase.\n */\nconst DEFAULT_INTERVAL_MILLIS = 1000;\n\n/**\n * The factor to backoff by.\n * Should be a number greater than 1.\n */\nconst DEFAULT_BACKOFF_FACTOR = 2;\n\n/**\n * The maximum milliseconds to increase to.\n *\n *

Visible for testing\n */\nexport const MAX_VALUE_MILLIS = 4 * 60 * 60 * 1000; // Four hours, like iOS and Android.\n\n/**\n * The percentage of backoff time to randomize by.\n * See\n * http://go/safe-client-behavior#step-1-determine-the-appropriate-retry-interval-to-handle-spike-traffic\n * for context.\n *\n *

Visible for testing\n */\nexport const RANDOM_FACTOR = 0.5;\n\n/**\n * Based on the backoff method from\n * https://github.com/google/closure-library/blob/master/closure/goog/math/exponentialbackoff.js.\n * Extracted here so we don't need to pass metadata and a stateful ExponentialBackoff object around.\n */\nexport function calculateBackoffMillis(\n backoffCount: number,\n intervalMillis: number = DEFAULT_INTERVAL_MILLIS,\n backoffFactor: number = DEFAULT_BACKOFF_FACTOR\n): number {\n // Calculates an exponentially increasing value.\n // Deviation: calculates value from count and a constant interval, so we only need to save value\n // and count to restore state.\n const currBaseValue = intervalMillis * Math.pow(backoffFactor, backoffCount);\n\n // A random \"fuzz\" to avoid waves of retries.\n // Deviation: randomFactor is required.\n const randomWait = Math.round(\n // A fraction of the backoff value to add/subtract.\n // Deviation: changes multiplication order to improve readability.\n RANDOM_FACTOR *\n currBaseValue *\n // A random float (rounded to int by Math.round above) in the range [-1, 1]. Determines\n // if we add or subtract.\n (Math.random() - 0.5) *\n 2\n );\n\n // Limits backoff to max to avoid effectively permanent backoff.\n return Math.min(MAX_VALUE_MILLIS, currBaseValue + randomWait);\n}\n", "/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Provide English ordinal letters after a number\n */\nexport function ordinal(i: number): string {\n if (!Number.isFinite(i)) {\n return `${i}`;\n }\n return i + indicator(i);\n}\n\nfunction indicator(i: number): string {\n i = Math.abs(i);\n const cent = i % 100;\n if (cent >= 10 && cent <= 20) {\n return 'th';\n }\n const dec = i % 10;\n if (dec === 1) {\n return 'st';\n }\n if (dec === 2) {\n return 'nd';\n }\n if (dec === 3) {\n return 'rd';\n }\n return 'th';\n}\n", "/**\n * @license\n * Copyright 2021 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport interface Compat {\n _delegate: T;\n}\n\nexport function getModularInstance(\n service: Compat | ExpService\n): ExpService {\n if (service && (service as Compat)._delegate) {\n return (service as Compat)._delegate;\n } else {\n return service as ExpService;\n }\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n InstantiationMode,\n InstanceFactory,\n ComponentType,\n Dictionary,\n Name,\n onInstanceCreatedCallback\n} from './types';\n\n/**\n * Component for service name T, e.g. `auth`, `auth-internal`\n */\nexport class Component {\n multipleInstances = false;\n /**\n * Properties to be added to the service namespace\n */\n serviceProps: Dictionary = {};\n\n instantiationMode = InstantiationMode.LAZY;\n\n onInstanceCreated: onInstanceCreatedCallback | null = null;\n\n /**\n *\n * @param name The public service name, e.g. app, auth, firestore, database\n * @param instanceFactory Service factory responsible for creating the public interface\n * @param type whether the service provided by the component is public or private\n */\n constructor(\n readonly name: T,\n readonly instanceFactory: InstanceFactory,\n readonly type: ComponentType\n ) {}\n\n setInstantiationMode(mode: InstantiationMode): this {\n this.instantiationMode = mode;\n return this;\n }\n\n setMultipleInstances(multipleInstances: boolean): this {\n this.multipleInstances = multipleInstances;\n return this;\n }\n\n setServiceProps(props: Dictionary): this {\n this.serviceProps = props;\n return this;\n }\n\n setInstanceCreatedCallback(callback: onInstanceCreatedCallback): this {\n this.onInstanceCreated = callback;\n return this;\n }\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport const DEFAULT_ENTRY_NAME = '[DEFAULT]';\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Deferred } from '@firebase/util';\nimport { ComponentContainer } from './component_container';\nimport { DEFAULT_ENTRY_NAME } from './constants';\nimport {\n InitializeOptions,\n InstantiationMode,\n Name,\n NameServiceMapping,\n OnInitCallBack\n} from './types';\nimport { Component } from './component';\n\n/**\n * Provider for instance for service name T, e.g. 'auth', 'auth-internal'\n * NameServiceMapping[T] is an alias for the type of the instance\n */\nexport class Provider {\n private component: Component | null = null;\n private readonly instances: Map = new Map();\n private readonly instancesDeferred: Map<\n string,\n Deferred\n > = new Map();\n private readonly instancesOptions: Map> =\n new Map();\n private onInitCallbacks: Map>> = new Map();\n\n constructor(\n private readonly name: T,\n private readonly container: ComponentContainer\n ) {}\n\n /**\n * @param identifier A provider can provide mulitple instances of a service\n * if this.component.multipleInstances is true.\n */\n get(identifier?: string): Promise {\n // if multipleInstances is not supported, use the default name\n const normalizedIdentifier = this.normalizeInstanceIdentifier(identifier);\n\n if (!this.instancesDeferred.has(normalizedIdentifier)) {\n const deferred = new Deferred();\n this.instancesDeferred.set(normalizedIdentifier, deferred);\n\n if (\n this.isInitialized(normalizedIdentifier) ||\n this.shouldAutoInitialize()\n ) {\n // initialize the service if it can be auto-initialized\n try {\n const instance = this.getOrInitializeService({\n instanceIdentifier: normalizedIdentifier\n });\n if (instance) {\n deferred.resolve(instance);\n }\n } catch (e) {\n // when the instance factory throws an exception during get(), it should not cause\n // a fatal error. We just return the unresolved promise in this case.\n }\n }\n }\n\n return this.instancesDeferred.get(normalizedIdentifier)!.promise;\n }\n\n /**\n *\n * @param options.identifier A provider can provide mulitple instances of a service\n * if this.component.multipleInstances is true.\n * @param options.optional If optional is false or not provided, the method throws an error when\n * the service is not immediately available.\n * If optional is true, the method returns null if the service is not immediately available.\n */\n getImmediate(options: {\n identifier?: string;\n optional: true;\n }): NameServiceMapping[T] | null;\n getImmediate(options?: {\n identifier?: string;\n optional?: false;\n }): NameServiceMapping[T];\n getImmediate(options?: {\n identifier?: string;\n optional?: boolean;\n }): NameServiceMapping[T] | null {\n // if multipleInstances is not supported, use the default name\n const normalizedIdentifier = this.normalizeInstanceIdentifier(\n options?.identifier\n );\n const optional = options?.optional ?? false;\n\n if (\n this.isInitialized(normalizedIdentifier) ||\n this.shouldAutoInitialize()\n ) {\n try {\n return this.getOrInitializeService({\n instanceIdentifier: normalizedIdentifier\n });\n } catch (e) {\n if (optional) {\n return null;\n } else {\n throw e;\n }\n }\n } else {\n // In case a component is not initialized and should/can not be auto-initialized at the moment, return null if the optional flag is set, or throw\n if (optional) {\n return null;\n } else {\n throw Error(`Service ${this.name} is not available`);\n }\n }\n }\n\n getComponent(): Component | null {\n return this.component;\n }\n\n setComponent(component: Component): void {\n if (component.name !== this.name) {\n throw Error(\n `Mismatching Component ${component.name} for Provider ${this.name}.`\n );\n }\n\n if (this.component) {\n throw Error(`Component for ${this.name} has already been provided`);\n }\n\n this.component = component;\n\n // return early without attempting to initialize the component if the component requires explicit initialization (calling `Provider.initialize()`)\n if (!this.shouldAutoInitialize()) {\n return;\n }\n\n // if the service is eager, initialize the default instance\n if (isComponentEager(component)) {\n try {\n this.getOrInitializeService({ instanceIdentifier: DEFAULT_ENTRY_NAME });\n } catch (e) {\n // when the instance factory for an eager Component throws an exception during the eager\n // initialization, it should not cause a fatal error.\n // TODO: Investigate if we need to make it configurable, because some component may want to cause\n // a fatal error in this case?\n }\n }\n\n // Create service instances for the pending promises and resolve them\n // NOTE: if this.multipleInstances is false, only the default instance will be created\n // and all promises with resolve with it regardless of the identifier.\n for (const [\n instanceIdentifier,\n instanceDeferred\n ] of this.instancesDeferred.entries()) {\n const normalizedIdentifier =\n this.normalizeInstanceIdentifier(instanceIdentifier);\n\n try {\n // `getOrInitializeService()` should always return a valid instance since a component is guaranteed. use ! to make typescript happy.\n const instance = this.getOrInitializeService({\n instanceIdentifier: normalizedIdentifier\n })!;\n instanceDeferred.resolve(instance);\n } catch (e) {\n // when the instance factory throws an exception, it should not cause\n // a fatal error. We just leave the promise unresolved.\n }\n }\n }\n\n clearInstance(identifier: string = DEFAULT_ENTRY_NAME): void {\n this.instancesDeferred.delete(identifier);\n this.instancesOptions.delete(identifier);\n this.instances.delete(identifier);\n }\n\n // app.delete() will call this method on every provider to delete the services\n // TODO: should we mark the provider as deleted?\n async delete(): Promise {\n const services = Array.from(this.instances.values());\n\n await Promise.all([\n ...services\n .filter(service => 'INTERNAL' in service) // legacy services\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n .map(service => (service as any).INTERNAL!.delete()),\n ...services\n .filter(service => '_delete' in service) // modularized services\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n .map(service => (service as any)._delete())\n ]);\n }\n\n isComponentSet(): boolean {\n return this.component != null;\n }\n\n isInitialized(identifier: string = DEFAULT_ENTRY_NAME): boolean {\n return this.instances.has(identifier);\n }\n\n getOptions(identifier: string = DEFAULT_ENTRY_NAME): Record {\n return this.instancesOptions.get(identifier) || {};\n }\n\n initialize(opts: InitializeOptions = {}): NameServiceMapping[T] {\n const { options = {} } = opts;\n const normalizedIdentifier = this.normalizeInstanceIdentifier(\n opts.instanceIdentifier\n );\n if (this.isInitialized(normalizedIdentifier)) {\n throw Error(\n `${this.name}(${normalizedIdentifier}) has already been initialized`\n );\n }\n\n if (!this.isComponentSet()) {\n throw Error(`Component ${this.name} has not been registered yet`);\n }\n\n const instance = this.getOrInitializeService({\n instanceIdentifier: normalizedIdentifier,\n options\n })!;\n\n // resolve any pending promise waiting for the service instance\n for (const [\n instanceIdentifier,\n instanceDeferred\n ] of this.instancesDeferred.entries()) {\n const normalizedDeferredIdentifier =\n this.normalizeInstanceIdentifier(instanceIdentifier);\n if (normalizedIdentifier === normalizedDeferredIdentifier) {\n instanceDeferred.resolve(instance);\n }\n }\n\n return instance;\n }\n\n /**\n *\n * @param callback - a function that will be invoked after the provider has been initialized by calling provider.initialize().\n * The function is invoked SYNCHRONOUSLY, so it should not execute any longrunning tasks in order to not block the program.\n *\n * @param identifier An optional instance identifier\n * @returns a function to unregister the callback\n */\n onInit(callback: OnInitCallBack, identifier?: string): () => void {\n const normalizedIdentifier = this.normalizeInstanceIdentifier(identifier);\n const existingCallbacks =\n this.onInitCallbacks.get(normalizedIdentifier) ??\n new Set>();\n existingCallbacks.add(callback);\n this.onInitCallbacks.set(normalizedIdentifier, existingCallbacks);\n\n const existingInstance = this.instances.get(normalizedIdentifier);\n if (existingInstance) {\n callback(existingInstance, normalizedIdentifier);\n }\n\n return () => {\n existingCallbacks.delete(callback);\n };\n }\n\n /**\n * Invoke onInit callbacks synchronously\n * @param instance the service instance`\n */\n private invokeOnInitCallbacks(\n instance: NameServiceMapping[T],\n identifier: string\n ): void {\n const callbacks = this.onInitCallbacks.get(identifier);\n if (!callbacks) {\n return;\n }\n for (const callback of callbacks) {\n try {\n callback(instance, identifier);\n } catch {\n // ignore errors in the onInit callback\n }\n }\n }\n\n private getOrInitializeService({\n instanceIdentifier,\n options = {}\n }: {\n instanceIdentifier: string;\n options?: Record;\n }): NameServiceMapping[T] | null {\n let instance = this.instances.get(instanceIdentifier);\n if (!instance && this.component) {\n instance = this.component.instanceFactory(this.container, {\n instanceIdentifier: normalizeIdentifierForFactory(instanceIdentifier),\n options\n });\n this.instances.set(instanceIdentifier, instance);\n this.instancesOptions.set(instanceIdentifier, options);\n\n /**\n * Invoke onInit listeners.\n * Note this.component.onInstanceCreated is different, which is used by the component creator,\n * while onInit listeners are registered by consumers of the provider.\n */\n this.invokeOnInitCallbacks(instance, instanceIdentifier);\n\n /**\n * Order is important\n * onInstanceCreated() should be called after this.instances.set(instanceIdentifier, instance); which\n * makes `isInitialized()` return true.\n */\n if (this.component.onInstanceCreated) {\n try {\n this.component.onInstanceCreated(\n this.container,\n instanceIdentifier,\n instance\n );\n } catch {\n // ignore errors in the onInstanceCreatedCallback\n }\n }\n }\n\n return instance || null;\n }\n\n private normalizeInstanceIdentifier(\n identifier: string = DEFAULT_ENTRY_NAME\n ): string {\n if (this.component) {\n return this.component.multipleInstances ? identifier : DEFAULT_ENTRY_NAME;\n } else {\n return identifier; // assume multiple instances are supported before the component is provided.\n }\n }\n\n private shouldAutoInitialize(): boolean {\n return (\n !!this.component &&\n this.component.instantiationMode !== InstantiationMode.EXPLICIT\n );\n }\n}\n\n// undefined should be passed to the service factory for the default instance\nfunction normalizeIdentifierForFactory(identifier: string): string | undefined {\n return identifier === DEFAULT_ENTRY_NAME ? undefined : identifier;\n}\n\nfunction isComponentEager(component: Component): boolean {\n return component.instantiationMode === InstantiationMode.EAGER;\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Provider } from './provider';\nimport { Component } from './component';\nimport { Name } from './types';\n\n/**\n * ComponentContainer that provides Providers for service name T, e.g. `auth`, `auth-internal`\n */\nexport class ComponentContainer {\n private readonly providers = new Map>();\n\n constructor(private readonly name: string) {}\n\n /**\n *\n * @param component Component being added\n * @param overwrite When a component with the same name has already been registered,\n * if overwrite is true: overwrite the existing component with the new component and create a new\n * provider with the new component. It can be useful in tests where you want to use different mocks\n * for different tests.\n * if overwrite is false: throw an exception\n */\n addComponent(component: Component): void {\n const provider = this.getProvider(component.name);\n if (provider.isComponentSet()) {\n throw new Error(\n `Component ${component.name} has already been registered with ${this.name}`\n );\n }\n\n provider.setComponent(component);\n }\n\n addOrOverwriteComponent(component: Component): void {\n const provider = this.getProvider(component.name);\n if (provider.isComponentSet()) {\n // delete the existing provider from the container, so we can register the new component\n this.providers.delete(component.name);\n }\n\n this.addComponent(component);\n }\n\n /**\n * getProvider provides a type safe interface where it can only be called with a field name\n * present in NameServiceMapping interface.\n *\n * Firebase SDKs providing services should extend NameServiceMapping interface to register\n * themselves.\n */\n getProvider(name: T): Provider {\n if (this.providers.has(name)) {\n return this.providers.get(name) as unknown as Provider;\n }\n\n // create a Provider for a service that hasn't registered with Firebase\n const provider = new Provider(name, this);\n this.providers.set(name, provider as unknown as Provider);\n\n return provider as Provider;\n }\n\n getProviders(): Array> {\n return Array.from(this.providers.values());\n }\n}\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport type LogLevelString =\n | 'debug'\n | 'verbose'\n | 'info'\n | 'warn'\n | 'error'\n | 'silent';\n\nexport interface LogOptions {\n level: LogLevelString;\n}\n\nexport type LogCallback = (callbackParams: LogCallbackParams) => void;\n\nexport interface LogCallbackParams {\n level: LogLevelString;\n message: string;\n args: unknown[];\n type: string;\n}\n\n/**\n * A container for all of the Logger instances\n */\nexport const instances: Logger[] = [];\n\n/**\n * The JS SDK supports 5 log levels and also allows a user the ability to\n * silence the logs altogether.\n *\n * The order is a follows:\n * DEBUG < VERBOSE < INFO < WARN < ERROR\n *\n * All of the log types above the current log level will be captured (i.e. if\n * you set the log level to `INFO`, errors will still be logged, but `DEBUG` and\n * `VERBOSE` logs will not)\n */\nexport enum LogLevel {\n DEBUG,\n VERBOSE,\n INFO,\n WARN,\n ERROR,\n SILENT\n}\n\nconst levelStringToEnum: { [key in LogLevelString]: LogLevel } = {\n 'debug': LogLevel.DEBUG,\n 'verbose': LogLevel.VERBOSE,\n 'info': LogLevel.INFO,\n 'warn': LogLevel.WARN,\n 'error': LogLevel.ERROR,\n 'silent': LogLevel.SILENT\n};\n\n/**\n * The default log level\n */\nconst defaultLogLevel: LogLevel = LogLevel.INFO;\n\n/**\n * We allow users the ability to pass their own log handler. We will pass the\n * type of log, the current log level, and any other arguments passed (i.e. the\n * messages that the user wants to log) to this function.\n */\nexport type LogHandler = (\n loggerInstance: Logger,\n logType: LogLevel,\n ...args: unknown[]\n) => void;\n\n/**\n * By default, `console.debug` is not displayed in the developer console (in\n * chrome). To avoid forcing users to have to opt-in to these logs twice\n * (i.e. once for firebase, and once in the console), we are sending `DEBUG`\n * logs to the `console.log` function.\n */\nconst ConsoleMethod = {\n [LogLevel.DEBUG]: 'log',\n [LogLevel.VERBOSE]: 'log',\n [LogLevel.INFO]: 'info',\n [LogLevel.WARN]: 'warn',\n [LogLevel.ERROR]: 'error'\n};\n\n/**\n * The default log handler will forward DEBUG, VERBOSE, INFO, WARN, and ERROR\n * messages on to their corresponding console counterparts (if the log method\n * is supported by the current log level)\n */\nconst defaultLogHandler: LogHandler = (instance, logType, ...args): void => {\n if (logType < instance.logLevel) {\n return;\n }\n const now = new Date().toISOString();\n const method = ConsoleMethod[logType as keyof typeof ConsoleMethod];\n if (method) {\n console[method as 'log' | 'info' | 'warn' | 'error'](\n `[${now}] ${instance.name}:`,\n ...args\n );\n } else {\n throw new Error(\n `Attempted to log a message with an invalid logType (value: ${logType})`\n );\n }\n};\n\nexport class Logger {\n /**\n * Gives you an instance of a Logger to capture messages according to\n * Firebase's logging scheme.\n *\n * @param name The name that the logs will be associated with\n */\n constructor(public name: string) {\n /**\n * Capture the current instance for later use\n */\n instances.push(this);\n }\n\n /**\n * The log level of the given Logger instance.\n */\n private _logLevel = defaultLogLevel;\n\n get logLevel(): LogLevel {\n return this._logLevel;\n }\n\n set logLevel(val: LogLevel) {\n if (!(val in LogLevel)) {\n throw new TypeError(`Invalid value \"${val}\" assigned to \\`logLevel\\``);\n }\n this._logLevel = val;\n }\n\n // Workaround for setter/getter having to be the same type.\n setLogLevel(val: LogLevel | LogLevelString): void {\n this._logLevel = typeof val === 'string' ? levelStringToEnum[val] : val;\n }\n\n /**\n * The main (internal) log handler for the Logger instance.\n * Can be set to a new function in internal package code but not by user.\n */\n private _logHandler: LogHandler = defaultLogHandler;\n get logHandler(): LogHandler {\n return this._logHandler;\n }\n set logHandler(val: LogHandler) {\n if (typeof val !== 'function') {\n throw new TypeError('Value assigned to `logHandler` must be a function');\n }\n this._logHandler = val;\n }\n\n /**\n * The optional, additional, user-defined log handler for the Logger instance.\n */\n private _userLogHandler: LogHandler | null = null;\n get userLogHandler(): LogHandler | null {\n return this._userLogHandler;\n }\n set userLogHandler(val: LogHandler | null) {\n this._userLogHandler = val;\n }\n\n /**\n * The functions below are all based on the `console` interface\n */\n\n debug(...args: unknown[]): void {\n this._userLogHandler && this._userLogHandler(this, LogLevel.DEBUG, ...args);\n this._logHandler(this, LogLevel.DEBUG, ...args);\n }\n log(...args: unknown[]): void {\n this._userLogHandler &&\n this._userLogHandler(this, LogLevel.VERBOSE, ...args);\n this._logHandler(this, LogLevel.VERBOSE, ...args);\n }\n info(...args: unknown[]): void {\n this._userLogHandler && this._userLogHandler(this, LogLevel.INFO, ...args);\n this._logHandler(this, LogLevel.INFO, ...args);\n }\n warn(...args: unknown[]): void {\n this._userLogHandler && this._userLogHandler(this, LogLevel.WARN, ...args);\n this._logHandler(this, LogLevel.WARN, ...args);\n }\n error(...args: unknown[]): void {\n this._userLogHandler && this._userLogHandler(this, LogLevel.ERROR, ...args);\n this._logHandler(this, LogLevel.ERROR, ...args);\n }\n}\n\nexport function setLogLevel(level: LogLevelString | LogLevel): void {\n instances.forEach(inst => {\n inst.setLogLevel(level);\n });\n}\n\nexport function setUserLogHandler(\n logCallback: LogCallback | null,\n options?: LogOptions\n): void {\n for (const instance of instances) {\n let customLogLevel: LogLevel | null = null;\n if (options && options.level) {\n customLogLevel = levelStringToEnum[options.level];\n }\n if (logCallback === null) {\n instance.userLogHandler = null;\n } else {\n instance.userLogHandler = (\n instance: Logger,\n level: LogLevel,\n ...args: unknown[]\n ) => {\n const message = args\n .map(arg => {\n if (arg == null) {\n return null;\n } else if (typeof arg === 'string') {\n return arg;\n } else if (typeof arg === 'number' || typeof arg === 'boolean') {\n return arg.toString();\n } else if (arg instanceof Error) {\n return arg.message;\n } else {\n try {\n return JSON.stringify(arg);\n } catch (ignored) {\n return null;\n }\n }\n })\n .filter(arg => arg)\n .join(' ');\n if (level >= (customLogLevel ?? instance.logLevel)) {\n logCallback({\n level: LogLevel[level].toLowerCase() as LogLevelString,\n message,\n args,\n type: instance.name\n });\n }\n };\n }\n }\n}\n", "const instanceOfAny = (object, constructors) => constructors.some((c) => object instanceof c);\n\nlet idbProxyableTypes;\nlet cursorAdvanceMethods;\n// This is a function to prevent it throwing up in node environments.\nfunction getIdbProxyableTypes() {\n return (idbProxyableTypes ||\n (idbProxyableTypes = [\n IDBDatabase,\n IDBObjectStore,\n IDBIndex,\n IDBCursor,\n IDBTransaction,\n ]));\n}\n// This is a function to prevent it throwing up in node environments.\nfunction getCursorAdvanceMethods() {\n return (cursorAdvanceMethods ||\n (cursorAdvanceMethods = [\n IDBCursor.prototype.advance,\n IDBCursor.prototype.continue,\n IDBCursor.prototype.continuePrimaryKey,\n ]));\n}\nconst cursorRequestMap = new WeakMap();\nconst transactionDoneMap = new WeakMap();\nconst transactionStoreNamesMap = new WeakMap();\nconst transformCache = new WeakMap();\nconst reverseTransformCache = new WeakMap();\nfunction promisifyRequest(request) {\n const promise = new Promise((resolve, reject) => {\n const unlisten = () => {\n request.removeEventListener('success', success);\n request.removeEventListener('error', error);\n };\n const success = () => {\n resolve(wrap(request.result));\n unlisten();\n };\n const error = () => {\n reject(request.error);\n unlisten();\n };\n request.addEventListener('success', success);\n request.addEventListener('error', error);\n });\n promise\n .then((value) => {\n // Since cursoring reuses the IDBRequest (*sigh*), we cache it for later retrieval\n // (see wrapFunction).\n if (value instanceof IDBCursor) {\n cursorRequestMap.set(value, request);\n }\n // Catching to avoid \"Uncaught Promise exceptions\"\n })\n .catch(() => { });\n // This mapping exists in reverseTransformCache but doesn't doesn't exist in transformCache. This\n // is because we create many promises from a single IDBRequest.\n reverseTransformCache.set(promise, request);\n return promise;\n}\nfunction cacheDonePromiseForTransaction(tx) {\n // Early bail if we've already created a done promise for this transaction.\n if (transactionDoneMap.has(tx))\n return;\n const done = new Promise((resolve, reject) => {\n const unlisten = () => {\n tx.removeEventListener('complete', complete);\n tx.removeEventListener('error', error);\n tx.removeEventListener('abort', error);\n };\n const complete = () => {\n resolve();\n unlisten();\n };\n const error = () => {\n reject(tx.error || new DOMException('AbortError', 'AbortError'));\n unlisten();\n };\n tx.addEventListener('complete', complete);\n tx.addEventListener('error', error);\n tx.addEventListener('abort', error);\n });\n // Cache it for later retrieval.\n transactionDoneMap.set(tx, done);\n}\nlet idbProxyTraps = {\n get(target, prop, receiver) {\n if (target instanceof IDBTransaction) {\n // Special handling for transaction.done.\n if (prop === 'done')\n return transactionDoneMap.get(target);\n // Polyfill for objectStoreNames because of Edge.\n if (prop === 'objectStoreNames') {\n return target.objectStoreNames || transactionStoreNamesMap.get(target);\n }\n // Make tx.store return the only store in the transaction, or undefined if there are many.\n if (prop === 'store') {\n return receiver.objectStoreNames[1]\n ? undefined\n : receiver.objectStore(receiver.objectStoreNames[0]);\n }\n }\n // Else transform whatever we get back.\n return wrap(target[prop]);\n },\n set(target, prop, value) {\n target[prop] = value;\n return true;\n },\n has(target, prop) {\n if (target instanceof IDBTransaction &&\n (prop === 'done' || prop === 'store')) {\n return true;\n }\n return prop in target;\n },\n};\nfunction replaceTraps(callback) {\n idbProxyTraps = callback(idbProxyTraps);\n}\nfunction wrapFunction(func) {\n // Due to expected object equality (which is enforced by the caching in `wrap`), we\n // only create one new func per func.\n // Edge doesn't support objectStoreNames (booo), so we polyfill it here.\n if (func === IDBDatabase.prototype.transaction &&\n !('objectStoreNames' in IDBTransaction.prototype)) {\n return function (storeNames, ...args) {\n const tx = func.call(unwrap(this), storeNames, ...args);\n transactionStoreNamesMap.set(tx, storeNames.sort ? storeNames.sort() : [storeNames]);\n return wrap(tx);\n };\n }\n // Cursor methods are special, as the behaviour is a little more different to standard IDB. In\n // IDB, you advance the cursor and wait for a new 'success' on the IDBRequest that gave you the\n // cursor. It's kinda like a promise that can resolve with many values. That doesn't make sense\n // with real promises, so each advance methods returns a new promise for the cursor object, or\n // undefined if the end of the cursor has been reached.\n if (getCursorAdvanceMethods().includes(func)) {\n return function (...args) {\n // Calling the original function with the proxy as 'this' causes ILLEGAL INVOCATION, so we use\n // the original object.\n func.apply(unwrap(this), args);\n return wrap(cursorRequestMap.get(this));\n };\n }\n return function (...args) {\n // Calling the original function with the proxy as 'this' causes ILLEGAL INVOCATION, so we use\n // the original object.\n return wrap(func.apply(unwrap(this), args));\n };\n}\nfunction transformCachableValue(value) {\n if (typeof value === 'function')\n return wrapFunction(value);\n // This doesn't return, it just creates a 'done' promise for the transaction,\n // which is later returned for transaction.done (see idbObjectHandler).\n if (value instanceof IDBTransaction)\n cacheDonePromiseForTransaction(value);\n if (instanceOfAny(value, getIdbProxyableTypes()))\n return new Proxy(value, idbProxyTraps);\n // Return the same value back if we're not going to transform it.\n return value;\n}\nfunction wrap(value) {\n // We sometimes generate multiple promises from a single IDBRequest (eg when cursoring), because\n // IDB is weird and a single IDBRequest can yield many responses, so these can't be cached.\n if (value instanceof IDBRequest)\n return promisifyRequest(value);\n // If we've already transformed this value before, reuse the transformed value.\n // This is faster, but it also provides object equality.\n if (transformCache.has(value))\n return transformCache.get(value);\n const newValue = transformCachableValue(value);\n // Not all types are transformed.\n // These may be primitive types, so they can't be WeakMap keys.\n if (newValue !== value) {\n transformCache.set(value, newValue);\n reverseTransformCache.set(newValue, value);\n }\n return newValue;\n}\nconst unwrap = (value) => reverseTransformCache.get(value);\n\nexport { reverseTransformCache as a, instanceOfAny as i, replaceTraps as r, unwrap as u, wrap as w };\n", "import { w as wrap, r as replaceTraps } from './wrap-idb-value.js';\nexport { u as unwrap, w as wrap } from './wrap-idb-value.js';\n\n/**\n * Open a database.\n *\n * @param name Name of the database.\n * @param version Schema version.\n * @param callbacks Additional callbacks.\n */\nfunction openDB(name, version, { blocked, upgrade, blocking, terminated } = {}) {\n const request = indexedDB.open(name, version);\n const openPromise = wrap(request);\n if (upgrade) {\n request.addEventListener('upgradeneeded', (event) => {\n upgrade(wrap(request.result), event.oldVersion, event.newVersion, wrap(request.transaction));\n });\n }\n if (blocked)\n request.addEventListener('blocked', () => blocked());\n openPromise\n .then((db) => {\n if (terminated)\n db.addEventListener('close', () => terminated());\n if (blocking)\n db.addEventListener('versionchange', () => blocking());\n })\n .catch(() => { });\n return openPromise;\n}\n/**\n * Delete a database.\n *\n * @param name Name of the database.\n */\nfunction deleteDB(name, { blocked } = {}) {\n const request = indexedDB.deleteDatabase(name);\n if (blocked)\n request.addEventListener('blocked', () => blocked());\n return wrap(request).then(() => undefined);\n}\n\nconst readMethods = ['get', 'getKey', 'getAll', 'getAllKeys', 'count'];\nconst writeMethods = ['put', 'add', 'delete', 'clear'];\nconst cachedMethods = new Map();\nfunction getMethod(target, prop) {\n if (!(target instanceof IDBDatabase &&\n !(prop in target) &&\n typeof prop === 'string')) {\n return;\n }\n if (cachedMethods.get(prop))\n return cachedMethods.get(prop);\n const targetFuncName = prop.replace(/FromIndex$/, '');\n const useIndex = prop !== targetFuncName;\n const isWrite = writeMethods.includes(targetFuncName);\n if (\n // Bail if the target doesn't exist on the target. Eg, getAll isn't in Edge.\n !(targetFuncName in (useIndex ? IDBIndex : IDBObjectStore).prototype) ||\n !(isWrite || readMethods.includes(targetFuncName))) {\n return;\n }\n const method = async function (storeName, ...args) {\n // isWrite ? 'readwrite' : undefined gzipps better, but fails in Edge :(\n const tx = this.transaction(storeName, isWrite ? 'readwrite' : 'readonly');\n let target = tx.store;\n if (useIndex)\n target = target.index(args.shift());\n // Must reject if op rejects.\n // If it's a write operation, must reject if tx.done rejects.\n // Must reject with op rejection first.\n // Must resolve with op value.\n // Must handle both promises (no unhandled rejections)\n return (await Promise.all([\n target[targetFuncName](...args),\n isWrite && tx.done,\n ]))[0];\n };\n cachedMethods.set(prop, method);\n return method;\n}\nreplaceTraps((oldTraps) => ({\n ...oldTraps,\n get: (target, prop, receiver) => getMethod(target, prop) || oldTraps.get(target, prop, receiver),\n has: (target, prop) => !!getMethod(target, prop) || oldTraps.has(target, prop),\n}));\n\nexport { deleteDB, openDB };\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n ComponentContainer,\n ComponentType,\n Provider,\n Name\n} from '@firebase/component';\nimport { PlatformLoggerService, VersionService } from './types';\n\nexport class PlatformLoggerServiceImpl implements PlatformLoggerService {\n constructor(private readonly container: ComponentContainer) {}\n // In initial implementation, this will be called by installations on\n // auth token refresh, and installations will send this string.\n getPlatformInfoString(): string {\n const providers = this.container.getProviders();\n // Loop through providers and get library/version pairs from any that are\n // version components.\n return providers\n .map(provider => {\n if (isVersionServiceProvider(provider)) {\n const service = provider.getImmediate() as VersionService;\n return `${service.library}/${service.version}`;\n } else {\n return null;\n }\n })\n .filter(logString => logString)\n .join(' ');\n }\n}\n/**\n *\n * @param provider check if this provider provides a VersionService\n *\n * NOTE: Using Provider<'app-version'> is a hack to indicate that the provider\n * provides VersionService. The provider is not necessarily a 'app-version'\n * provider.\n */\nfunction isVersionServiceProvider(provider: Provider): boolean {\n const component = provider.getComponent();\n return component?.type === ComponentType.VERSION;\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Logger } from '@firebase/logger';\n\nexport const logger = new Logger('@firebase/app');\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { name as appName } from '../package.json';\nimport { name as appCompatName } from '../../app-compat/package.json';\nimport { name as analyticsCompatName } from '../../../packages/analytics-compat/package.json';\nimport { name as analyticsName } from '../../../packages/analytics/package.json';\nimport { name as appCheckCompatName } from '../../../packages/app-check-compat/package.json';\nimport { name as appCheckName } from '../../../packages/app-check/package.json';\nimport { name as authName } from '../../../packages/auth/package.json';\nimport { name as authCompatName } from '../../../packages/auth-compat/package.json';\nimport { name as databaseName } from '../../../packages/database/package.json';\nimport { name as databaseCompatName } from '../../../packages/database-compat/package.json';\nimport { name as functionsName } from '../../../packages/functions/package.json';\nimport { name as functionsCompatName } from '../../../packages/functions-compat/package.json';\nimport { name as installationsName } from '../../../packages/installations/package.json';\nimport { name as installationsCompatName } from '../../../packages/installations-compat/package.json';\nimport { name as messagingName } from '../../../packages/messaging/package.json';\nimport { name as messagingCompatName } from '../../../packages/messaging-compat/package.json';\nimport { name as performanceName } from '../../../packages/performance/package.json';\nimport { name as performanceCompatName } from '../../../packages/performance-compat/package.json';\nimport { name as remoteConfigName } from '../../../packages/remote-config/package.json';\nimport { name as remoteConfigCompatName } from '../../../packages/remote-config-compat/package.json';\nimport { name as storageName } from '../../../packages/storage/package.json';\nimport { name as storageCompatName } from '../../../packages/storage-compat/package.json';\nimport { name as firestoreName } from '../../../packages/firestore/package.json';\nimport { name as firestoreCompatName } from '../../../packages/firestore-compat/package.json';\nimport { name as packageName } from '../../../packages/firebase/package.json';\n\n/**\n * The default app name\n *\n * @internal\n */\nexport const DEFAULT_ENTRY_NAME = '[DEFAULT]';\n\nexport const PLATFORM_LOG_STRING = {\n [appName]: 'fire-core',\n [appCompatName]: 'fire-core-compat',\n [analyticsName]: 'fire-analytics',\n [analyticsCompatName]: 'fire-analytics-compat',\n [appCheckName]: 'fire-app-check',\n [appCheckCompatName]: 'fire-app-check-compat',\n [authName]: 'fire-auth',\n [authCompatName]: 'fire-auth-compat',\n [databaseName]: 'fire-rtdb',\n [databaseCompatName]: 'fire-rtdb-compat',\n [functionsName]: 'fire-fn',\n [functionsCompatName]: 'fire-fn-compat',\n [installationsName]: 'fire-iid',\n [installationsCompatName]: 'fire-iid-compat',\n [messagingName]: 'fire-fcm',\n [messagingCompatName]: 'fire-fcm-compat',\n [performanceName]: 'fire-perf',\n [performanceCompatName]: 'fire-perf-compat',\n [remoteConfigName]: 'fire-rc',\n [remoteConfigCompatName]: 'fire-rc-compat',\n [storageName]: 'fire-gcs',\n [storageCompatName]: 'fire-gcs-compat',\n [firestoreName]: 'fire-fst',\n [firestoreCompatName]: 'fire-fst-compat',\n 'fire-js': 'fire-js', // Platform identifier for JS SDK.\n [packageName]: 'fire-js-all'\n} as const;\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { FirebaseApp } from './public-types';\nimport { Component, Provider, Name } from '@firebase/component';\nimport { logger } from './logger';\nimport { DEFAULT_ENTRY_NAME } from './constants';\nimport { FirebaseAppImpl } from './firebaseApp';\n\n/**\n * @internal\n */\nexport const _apps = new Map();\n\n/**\n * Registered components.\n *\n * @internal\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport const _components = new Map>();\n\n/**\n * @param component - the component being added to this app's container\n *\n * @internal\n */\nexport function _addComponent(\n app: FirebaseApp,\n component: Component\n): void {\n try {\n (app as FirebaseAppImpl).container.addComponent(component);\n } catch (e) {\n logger.debug(\n `Component ${component.name} failed to register with FirebaseApp ${app.name}`,\n e\n );\n }\n}\n\n/**\n *\n * @internal\n */\nexport function _addOrOverwriteComponent(\n app: FirebaseApp,\n component: Component\n): void {\n (app as FirebaseAppImpl).container.addOrOverwriteComponent(component);\n}\n\n/**\n *\n * @param component - the component to register\n * @returns whether or not the component is registered successfully\n *\n * @internal\n */\nexport function _registerComponent(\n component: Component\n): boolean {\n const componentName = component.name;\n if (_components.has(componentName)) {\n logger.debug(\n `There were multiple attempts to register component ${componentName}.`\n );\n\n return false;\n }\n\n _components.set(componentName, component);\n\n // add the component to existing app instances\n for (const app of _apps.values()) {\n _addComponent(app as FirebaseAppImpl, component);\n }\n\n return true;\n}\n\n/**\n *\n * @param app - FirebaseApp instance\n * @param name - service name\n *\n * @returns the provider for the service with the matching name\n *\n * @internal\n */\nexport function _getProvider(\n app: FirebaseApp,\n name: T\n): Provider {\n const heartbeatController = (app as FirebaseAppImpl).container\n .getProvider('heartbeat')\n .getImmediate({ optional: true });\n if (heartbeatController) {\n void heartbeatController.triggerHeartbeat();\n }\n return (app as FirebaseAppImpl).container.getProvider(name);\n}\n\n/**\n *\n * @param app - FirebaseApp instance\n * @param name - service name\n * @param instanceIdentifier - service instance identifier in case the service supports multiple instances\n *\n * @internal\n */\nexport function _removeServiceInstance(\n app: FirebaseApp,\n name: T,\n instanceIdentifier: string = DEFAULT_ENTRY_NAME\n): void {\n _getProvider(app, name).clearInstance(instanceIdentifier);\n}\n\n/**\n * Test only\n *\n * @internal\n */\nexport function _clearComponents(): void {\n _components.clear();\n}\n\n/**\n * Exported in order to be used in app-compat package\n */\nexport { DEFAULT_ENTRY_NAME as _DEFAULT_ENTRY_NAME };\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ErrorFactory, ErrorMap } from '@firebase/util';\n\nexport const enum AppError {\n NO_APP = 'no-app',\n BAD_APP_NAME = 'bad-app-name',\n DUPLICATE_APP = 'duplicate-app',\n APP_DELETED = 'app-deleted',\n INVALID_APP_ARGUMENT = 'invalid-app-argument',\n INVALID_LOG_ARGUMENT = 'invalid-log-argument',\n IDB_OPEN = 'idb-open',\n IDB_GET = 'idb-get',\n IDB_WRITE = 'idb-set',\n IDB_DELETE = 'idb-delete'\n}\n\nconst ERRORS: ErrorMap = {\n [AppError.NO_APP]:\n \"No Firebase App '{$appName}' has been created - \" +\n 'call Firebase App.initializeApp()',\n [AppError.BAD_APP_NAME]: \"Illegal App name: '{$appName}\",\n [AppError.DUPLICATE_APP]:\n \"Firebase App named '{$appName}' already exists with different options or config\",\n [AppError.APP_DELETED]: \"Firebase App named '{$appName}' already deleted\",\n [AppError.INVALID_APP_ARGUMENT]:\n 'firebase.{$appName}() takes either no argument or a ' +\n 'Firebase App instance.',\n [AppError.INVALID_LOG_ARGUMENT]:\n 'First argument to `onLog` must be null or a function.',\n [AppError.IDB_OPEN]:\n 'Error thrown when opening IndexedDB. Original error: {$originalErrorMessage}.',\n [AppError.IDB_GET]:\n 'Error thrown when reading from IndexedDB. Original error: {$originalErrorMessage}.',\n [AppError.IDB_WRITE]:\n 'Error thrown when writing to IndexedDB. Original error: {$originalErrorMessage}.',\n [AppError.IDB_DELETE]:\n 'Error thrown when deleting from IndexedDB. Original error: {$originalErrorMessage}.'\n};\n\ninterface ErrorParams {\n [AppError.NO_APP]: { appName: string };\n [AppError.BAD_APP_NAME]: { appName: string };\n [AppError.DUPLICATE_APP]: { appName: string };\n [AppError.APP_DELETED]: { appName: string };\n [AppError.INVALID_APP_ARGUMENT]: { appName: string };\n [AppError.IDB_OPEN]: { originalErrorMessage?: string };\n [AppError.IDB_GET]: { originalErrorMessage?: string };\n [AppError.IDB_WRITE]: { originalErrorMessage?: string };\n [AppError.IDB_DELETE]: { originalErrorMessage?: string };\n}\n\nexport const ERROR_FACTORY = new ErrorFactory(\n 'app',\n 'Firebase',\n ERRORS\n);\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n FirebaseApp,\n FirebaseOptions,\n FirebaseAppSettings\n} from './public-types';\nimport {\n ComponentContainer,\n Component,\n ComponentType\n} from '@firebase/component';\nimport { ERROR_FACTORY, AppError } from './errors';\n\nexport class FirebaseAppImpl implements FirebaseApp {\n private readonly _options: FirebaseOptions;\n private readonly _name: string;\n /**\n * Original config values passed in as a constructor parameter.\n * It is only used to compare with another config object to support idempotent initializeApp().\n *\n * Updating automaticDataCollectionEnabled on the App instance will not change its value in _config.\n */\n private readonly _config: Required;\n private _automaticDataCollectionEnabled: boolean;\n private _isDeleted = false;\n private readonly _container: ComponentContainer;\n\n constructor(\n options: FirebaseOptions,\n config: Required,\n container: ComponentContainer\n ) {\n this._options = { ...options };\n this._config = { ...config };\n this._name = config.name;\n this._automaticDataCollectionEnabled =\n config.automaticDataCollectionEnabled;\n this._container = container;\n this.container.addComponent(\n new Component('app', () => this, ComponentType.PUBLIC)\n );\n }\n\n get automaticDataCollectionEnabled(): boolean {\n this.checkDestroyed();\n return this._automaticDataCollectionEnabled;\n }\n\n set automaticDataCollectionEnabled(val: boolean) {\n this.checkDestroyed();\n this._automaticDataCollectionEnabled = val;\n }\n\n get name(): string {\n this.checkDestroyed();\n return this._name;\n }\n\n get options(): FirebaseOptions {\n this.checkDestroyed();\n return this._options;\n }\n\n get config(): Required {\n this.checkDestroyed();\n return this._config;\n }\n\n get container(): ComponentContainer {\n return this._container;\n }\n\n get isDeleted(): boolean {\n return this._isDeleted;\n }\n\n set isDeleted(val: boolean) {\n this._isDeleted = val;\n }\n\n /**\n * This function will throw an Error if the App has already been deleted -\n * use before performing API actions on the App.\n */\n private checkDestroyed(): void {\n if (this.isDeleted) {\n throw ERROR_FACTORY.create(AppError.APP_DELETED, { appName: this._name });\n }\n }\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n FirebaseApp,\n FirebaseOptions,\n FirebaseAppSettings\n} from './public-types';\nimport { DEFAULT_ENTRY_NAME, PLATFORM_LOG_STRING } from './constants';\nimport { ERROR_FACTORY, AppError } from './errors';\nimport {\n ComponentContainer,\n Component,\n Name,\n ComponentType\n} from '@firebase/component';\nimport { version } from '../../firebase/package.json';\nimport { FirebaseAppImpl } from './firebaseApp';\nimport { _apps, _components, _registerComponent } from './internal';\nimport { logger } from './logger';\nimport {\n LogLevelString,\n setLogLevel as setLogLevelImpl,\n LogCallback,\n LogOptions,\n setUserLogHandler\n} from '@firebase/logger';\nimport { deepEqual } from '@firebase/util';\n\nexport { FirebaseError } from '@firebase/util';\n\n/**\n * The current SDK version.\n *\n * @public\n */\nexport const SDK_VERSION = version;\n\n/**\n * Creates and initializes a {@link @firebase/app#FirebaseApp} instance.\n *\n * See\n * {@link\n * https://firebase.google.com/docs/web/setup#add_firebase_to_your_app\n * | Add Firebase to your app} and\n * {@link\n * https://firebase.google.com/docs/web/setup#multiple-projects\n * | Initialize multiple projects} for detailed documentation.\n *\n * @example\n * ```javascript\n *\n * // Initialize default app\n * // Retrieve your own options values by adding a web app on\n * // https://console.firebase.google.com\n * initializeApp({\n * apiKey: \"AIza....\", // Auth / General Use\n * authDomain: \"YOUR_APP.firebaseapp.com\", // Auth with popup/redirect\n * databaseURL: \"https://YOUR_APP.firebaseio.com\", // Realtime Database\n * storageBucket: \"YOUR_APP.appspot.com\", // Storage\n * messagingSenderId: \"123456789\" // Cloud Messaging\n * });\n * ```\n *\n * @example\n * ```javascript\n *\n * // Initialize another app\n * const otherApp = initializeApp({\n * databaseURL: \"https://.firebaseio.com\",\n * storageBucket: \".appspot.com\"\n * }, \"otherApp\");\n * ```\n *\n * @param options - Options to configure the app's services.\n * @param name - Optional name of the app to initialize. If no name\n * is provided, the default is `\"[DEFAULT]\"`.\n *\n * @returns The initialized app.\n *\n * @public\n */\nexport function initializeApp(\n options: FirebaseOptions,\n name?: string\n): FirebaseApp;\n/**\n * Creates and initializes a FirebaseApp instance.\n *\n * @param options - Options to configure the app's services.\n * @param config - FirebaseApp Configuration\n *\n * @public\n */\nexport function initializeApp(\n options: FirebaseOptions,\n config?: FirebaseAppSettings\n): FirebaseApp;\nexport function initializeApp(\n options: FirebaseOptions,\n rawConfig = {}\n): FirebaseApp {\n if (typeof rawConfig !== 'object') {\n const name = rawConfig;\n rawConfig = { name };\n }\n\n const config: Required = {\n name: DEFAULT_ENTRY_NAME,\n automaticDataCollectionEnabled: false,\n ...rawConfig\n };\n const name = config.name;\n\n if (typeof name !== 'string' || !name) {\n throw ERROR_FACTORY.create(AppError.BAD_APP_NAME, {\n appName: String(name)\n });\n }\n\n const existingApp = _apps.get(name) as FirebaseAppImpl;\n if (existingApp) {\n // return the existing app if options and config deep equal the ones in the existing app.\n if (\n deepEqual(options, existingApp.options) &&\n deepEqual(config, existingApp.config)\n ) {\n return existingApp;\n } else {\n throw ERROR_FACTORY.create(AppError.DUPLICATE_APP, { appName: name });\n }\n }\n\n const container = new ComponentContainer(name);\n for (const component of _components.values()) {\n container.addComponent(component);\n }\n\n const newApp = new FirebaseAppImpl(options, config, container);\n\n _apps.set(name, newApp);\n\n return newApp;\n}\n\n/**\n * Retrieves a {@link @firebase/app#FirebaseApp} instance.\n *\n * When called with no arguments, the default app is returned. When an app name\n * is provided, the app corresponding to that name is returned.\n *\n * An exception is thrown if the app being retrieved has not yet been\n * initialized.\n *\n * @example\n * ```javascript\n * // Return the default app\n * const app = getApp();\n * ```\n *\n * @example\n * ```javascript\n * // Return a named app\n * const otherApp = getApp(\"otherApp\");\n * ```\n *\n * @param name - Optional name of the app to return. If no name is\n * provided, the default is `\"[DEFAULT]\"`.\n *\n * @returns The app corresponding to the provided app name.\n * If no app name is provided, the default app is returned.\n *\n * @public\n */\nexport function getApp(name: string = DEFAULT_ENTRY_NAME): FirebaseApp {\n const app = _apps.get(name);\n if (!app) {\n throw ERROR_FACTORY.create(AppError.NO_APP, { appName: name });\n }\n\n return app;\n}\n\n/**\n * A (read-only) array of all initialized apps.\n * @public\n */\nexport function getApps(): FirebaseApp[] {\n return Array.from(_apps.values());\n}\n\n/**\n * Renders this app unusable and frees the resources of all associated\n * services.\n *\n * @example\n * ```javascript\n * deleteApp(app)\n * .then(function() {\n * console.log(\"App deleted successfully\");\n * })\n * .catch(function(error) {\n * console.log(\"Error deleting app:\", error);\n * });\n * ```\n *\n * @public\n */\nexport async function deleteApp(app: FirebaseApp): Promise {\n const name = app.name;\n if (_apps.has(name)) {\n _apps.delete(name);\n await Promise.all(\n (app as FirebaseAppImpl).container\n .getProviders()\n .map(provider => provider.delete())\n );\n (app as FirebaseAppImpl).isDeleted = true;\n }\n}\n\n/**\n * Registers a library's name and version for platform logging purposes.\n * @param library - Name of 1p or 3p library (e.g. firestore, angularfire)\n * @param version - Current version of that library.\n * @param variant - Bundle variant, e.g., node, rn, etc.\n *\n * @public\n */\nexport function registerVersion(\n libraryKeyOrName: string,\n version: string,\n variant?: string\n): void {\n // TODO: We can use this check to whitelist strings when/if we set up\n // a good whitelist system.\n let library = PLATFORM_LOG_STRING[libraryKeyOrName] ?? libraryKeyOrName;\n if (variant) {\n library += `-${variant}`;\n }\n const libraryMismatch = library.match(/\\s|\\//);\n const versionMismatch = version.match(/\\s|\\//);\n if (libraryMismatch || versionMismatch) {\n const warning = [\n `Unable to register library \"${library}\" with version \"${version}\":`\n ];\n if (libraryMismatch) {\n warning.push(\n `library name \"${library}\" contains illegal characters (whitespace or \"/\")`\n );\n }\n if (libraryMismatch && versionMismatch) {\n warning.push('and');\n }\n if (versionMismatch) {\n warning.push(\n `version name \"${version}\" contains illegal characters (whitespace or \"/\")`\n );\n }\n logger.warn(warning.join(' '));\n return;\n }\n _registerComponent(\n new Component(\n `${library}-version` as Name,\n () => ({ library, version }),\n ComponentType.VERSION\n )\n );\n}\n\n/**\n * Sets log handler for all Firebase SDKs.\n * @param logCallback - An optional custom log handler that executes user code whenever\n * the Firebase SDK makes a logging call.\n *\n * @public\n */\nexport function onLog(\n logCallback: LogCallback | null,\n options?: LogOptions\n): void {\n if (logCallback !== null && typeof logCallback !== 'function') {\n throw ERROR_FACTORY.create(AppError.INVALID_LOG_ARGUMENT);\n }\n setUserLogHandler(logCallback, options);\n}\n\n/**\n * Sets log level for all Firebase SDKs.\n *\n * All of the log types above the current log level are captured (i.e. if\n * you set the log level to `info`, errors are logged, but `debug` and\n * `verbose` logs are not).\n *\n * @public\n */\nexport function setLogLevel(logLevel: LogLevelString): void {\n setLogLevelImpl(logLevel);\n}\n", "/**\n * @license\n * Copyright 2021 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { FirebaseError } from '@firebase/util';\nimport { DBSchema, openDB, IDBPDatabase } from 'idb';\nimport { AppError, ERROR_FACTORY } from './errors';\nimport { FirebaseApp } from './public-types';\nimport { HeartbeatsInIndexedDB } from './types';\nimport { logger } from './logger';\n\nconst DB_NAME = 'firebase-heartbeat-database';\nconst DB_VERSION = 1;\nconst STORE_NAME = 'firebase-heartbeat-store';\n\ninterface AppDB extends DBSchema {\n 'firebase-heartbeat-store': {\n key: string;\n value: HeartbeatsInIndexedDB;\n };\n}\n\nlet dbPromise: Promise> | null = null;\nfunction getDbPromise(): Promise> {\n if (!dbPromise) {\n dbPromise = openDB(DB_NAME, DB_VERSION, {\n upgrade: (db, oldVersion) => {\n // We don't use 'break' in this switch statement, the fall-through\n // behavior is what we want, because if there are multiple versions between\n // the old version and the current version, we want ALL the migrations\n // that correspond to those versions to run, not only the last one.\n // eslint-disable-next-line default-case\n switch (oldVersion) {\n case 0:\n db.createObjectStore(STORE_NAME);\n }\n }\n }).catch(e => {\n throw ERROR_FACTORY.create(AppError.IDB_OPEN, {\n originalErrorMessage: e.message\n });\n });\n }\n return dbPromise;\n}\n\nexport async function readHeartbeatsFromIndexedDB(\n app: FirebaseApp\n): Promise {\n try {\n const db = await getDbPromise();\n return db\n .transaction(STORE_NAME)\n .objectStore(STORE_NAME)\n .get(computeKey(app)) as Promise;\n } catch (e) {\n if (e instanceof FirebaseError) {\n logger.warn(e.message);\n } else {\n const idbGetError = ERROR_FACTORY.create(AppError.IDB_GET, {\n originalErrorMessage: (e as Error)?.message\n });\n logger.warn(idbGetError.message);\n }\n }\n}\n\nexport async function writeHeartbeatsToIndexedDB(\n app: FirebaseApp,\n heartbeatObject: HeartbeatsInIndexedDB\n): Promise {\n try {\n const db = await getDbPromise();\n const tx = db.transaction(STORE_NAME, 'readwrite');\n const objectStore = tx.objectStore(STORE_NAME);\n await objectStore.put(heartbeatObject, computeKey(app));\n return tx.done;\n } catch (e) {\n if (e instanceof FirebaseError) {\n logger.warn(e.message);\n } else {\n const idbGetError = ERROR_FACTORY.create(AppError.IDB_WRITE, {\n originalErrorMessage: (e as Error)?.message\n });\n logger.warn(idbGetError.message);\n }\n }\n}\n\nfunction computeKey(app: FirebaseApp): string {\n return `${app.name}!${app.options.appId}`;\n}\n", "/**\n * @license\n * Copyright 2021 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ComponentContainer } from '@firebase/component';\nimport {\n base64urlEncodeWithoutPadding,\n isIndexedDBAvailable,\n validateIndexedDBOpenable\n} from '@firebase/util';\nimport {\n readHeartbeatsFromIndexedDB,\n writeHeartbeatsToIndexedDB\n} from './indexeddb';\nimport { FirebaseApp } from './public-types';\nimport {\n HeartbeatsByUserAgent,\n HeartbeatService,\n HeartbeatsInIndexedDB,\n HeartbeatStorage,\n SingleDateHeartbeat\n} from './types';\n\nconst MAX_HEADER_BYTES = 1024;\n// 30 days\nconst STORED_HEARTBEAT_RETENTION_MAX_MILLIS = 30 * 24 * 60 * 60 * 1000;\n\nexport class HeartbeatServiceImpl implements HeartbeatService {\n /**\n * The persistence layer for heartbeats\n * Leave public for easier testing.\n */\n _storage: HeartbeatStorageImpl;\n\n /**\n * In-memory cache for heartbeats, used by getHeartbeatsHeader() to generate\n * the header string.\n * Stores one record per date. This will be consolidated into the standard\n * format of one record per user agent string before being sent as a header.\n * Populated from indexedDB when the controller is instantiated and should\n * be kept in sync with indexedDB.\n * Leave public for easier testing.\n */\n _heartbeatsCache: HeartbeatsInIndexedDB | null = null;\n\n /**\n * the initialization promise for populating heartbeatCache.\n * If getHeartbeatsHeader() is called before the promise resolves\n * (hearbeatsCache == null), it should wait for this promise\n * Leave public for easier testing.\n */\n _heartbeatsCachePromise: Promise;\n constructor(private readonly container: ComponentContainer) {\n const app = this.container.getProvider('app').getImmediate();\n this._storage = new HeartbeatStorageImpl(app);\n this._heartbeatsCachePromise = this._storage.read().then(result => {\n this._heartbeatsCache = result;\n return result;\n });\n }\n\n /**\n * Called to report a heartbeat. The function will generate\n * a HeartbeatsByUserAgent object, update heartbeatsCache, and persist it\n * to IndexedDB.\n * Note that we only store one heartbeat per day. So if a heartbeat for today is\n * already logged, subsequent calls to this function in the same day will be ignored.\n */\n async triggerHeartbeat(): Promise {\n const platformLogger = this.container\n .getProvider('platform-logger')\n .getImmediate();\n\n // This is the \"Firebase user agent\" string from the platform logger\n // service, not the browser user agent.\n const agent = platformLogger.getPlatformInfoString();\n const date = getUTCDateString();\n if (this._heartbeatsCache === null) {\n this._heartbeatsCache = await this._heartbeatsCachePromise;\n }\n // Do not store a heartbeat if one is already stored for this day\n // or if a header has already been sent today.\n if (\n this._heartbeatsCache.lastSentHeartbeatDate === date ||\n this._heartbeatsCache.heartbeats.some(\n singleDateHeartbeat => singleDateHeartbeat.date === date\n )\n ) {\n return;\n } else {\n // There is no entry for this date. Create one.\n this._heartbeatsCache.heartbeats.push({ date, agent });\n }\n // Remove entries older than 30 days.\n this._heartbeatsCache.heartbeats = this._heartbeatsCache.heartbeats.filter(\n singleDateHeartbeat => {\n const hbTimestamp = new Date(singleDateHeartbeat.date).valueOf();\n const now = Date.now();\n return now - hbTimestamp <= STORED_HEARTBEAT_RETENTION_MAX_MILLIS;\n }\n );\n return this._storage.overwrite(this._heartbeatsCache);\n }\n\n /**\n * Returns a base64 encoded string which can be attached to the heartbeat-specific header directly.\n * It also clears all heartbeats from memory as well as in IndexedDB.\n *\n * NOTE: Consuming product SDKs should not send the header if this method\n * returns an empty string.\n */\n async getHeartbeatsHeader(): Promise {\n if (this._heartbeatsCache === null) {\n await this._heartbeatsCachePromise;\n }\n // If it's still null or the array is empty, there is no data to send.\n if (\n this._heartbeatsCache === null ||\n this._heartbeatsCache.heartbeats.length === 0\n ) {\n return '';\n }\n const date = getUTCDateString();\n // Extract as many heartbeats from the cache as will fit under the size limit.\n const { heartbeatsToSend, unsentEntries } = extractHeartbeatsForHeader(\n this._heartbeatsCache.heartbeats\n );\n const headerString = base64urlEncodeWithoutPadding(\n JSON.stringify({ version: 2, heartbeats: heartbeatsToSend })\n );\n // Store last sent date to prevent another being logged/sent for the same day.\n this._heartbeatsCache.lastSentHeartbeatDate = date;\n if (unsentEntries.length > 0) {\n // Store any unsent entries if they exist.\n this._heartbeatsCache.heartbeats = unsentEntries;\n // This seems more likely than emptying the array (below) to lead to some odd state\n // since the cache isn't empty and this will be called again on the next request,\n // and is probably safest if we await it.\n await this._storage.overwrite(this._heartbeatsCache);\n } else {\n this._heartbeatsCache.heartbeats = [];\n // Do not wait for this, to reduce latency.\n void this._storage.overwrite(this._heartbeatsCache);\n }\n return headerString;\n }\n}\n\nfunction getUTCDateString(): string {\n const today = new Date();\n // Returns date format 'YYYY-MM-DD'\n return today.toISOString().substring(0, 10);\n}\n\nexport function extractHeartbeatsForHeader(\n heartbeatsCache: SingleDateHeartbeat[],\n maxSize = MAX_HEADER_BYTES\n): {\n heartbeatsToSend: HeartbeatsByUserAgent[];\n unsentEntries: SingleDateHeartbeat[];\n} {\n // Heartbeats grouped by user agent in the standard format to be sent in\n // the header.\n const heartbeatsToSend: HeartbeatsByUserAgent[] = [];\n // Single date format heartbeats that are not sent.\n let unsentEntries = heartbeatsCache.slice();\n for (const singleDateHeartbeat of heartbeatsCache) {\n // Look for an existing entry with the same user agent.\n const heartbeatEntry = heartbeatsToSend.find(\n hb => hb.agent === singleDateHeartbeat.agent\n );\n if (!heartbeatEntry) {\n // If no entry for this user agent exists, create one.\n heartbeatsToSend.push({\n agent: singleDateHeartbeat.agent,\n dates: [singleDateHeartbeat.date]\n });\n if (countBytes(heartbeatsToSend) > maxSize) {\n // If the header would exceed max size, remove the added heartbeat\n // entry and stop adding to the header.\n heartbeatsToSend.pop();\n break;\n }\n } else {\n heartbeatEntry.dates.push(singleDateHeartbeat.date);\n // If the header would exceed max size, remove the added date\n // and stop adding to the header.\n if (countBytes(heartbeatsToSend) > maxSize) {\n heartbeatEntry.dates.pop();\n break;\n }\n }\n // Pop unsent entry from queue. (Skipped if adding the entry exceeded\n // quota and the loop breaks early.)\n unsentEntries = unsentEntries.slice(1);\n }\n return {\n heartbeatsToSend,\n unsentEntries\n };\n}\n\nexport class HeartbeatStorageImpl implements HeartbeatStorage {\n private _canUseIndexedDBPromise: Promise;\n constructor(public app: FirebaseApp) {\n this._canUseIndexedDBPromise = this.runIndexedDBEnvironmentCheck();\n }\n async runIndexedDBEnvironmentCheck(): Promise {\n if (!isIndexedDBAvailable()) {\n return false;\n } else {\n return validateIndexedDBOpenable()\n .then(() => true)\n .catch(() => false);\n }\n }\n /**\n * Read all heartbeats.\n */\n async read(): Promise {\n const canUseIndexedDB = await this._canUseIndexedDBPromise;\n if (!canUseIndexedDB) {\n return { heartbeats: [] };\n } else {\n const idbHeartbeatObject = await readHeartbeatsFromIndexedDB(this.app);\n return idbHeartbeatObject || { heartbeats: [] };\n }\n }\n // overwrite the storage with the provided heartbeats\n async overwrite(heartbeatsObject: HeartbeatsInIndexedDB): Promise {\n const canUseIndexedDB = await this._canUseIndexedDBPromise;\n if (!canUseIndexedDB) {\n return;\n } else {\n const existingHeartbeatsObject = await this.read();\n return writeHeartbeatsToIndexedDB(this.app, {\n lastSentHeartbeatDate:\n heartbeatsObject.lastSentHeartbeatDate ??\n existingHeartbeatsObject.lastSentHeartbeatDate,\n heartbeats: heartbeatsObject.heartbeats\n });\n }\n }\n // add heartbeats\n async add(heartbeatsObject: HeartbeatsInIndexedDB): Promise {\n const canUseIndexedDB = await this._canUseIndexedDBPromise;\n if (!canUseIndexedDB) {\n return;\n } else {\n const existingHeartbeatsObject = await this.read();\n return writeHeartbeatsToIndexedDB(this.app, {\n lastSentHeartbeatDate:\n heartbeatsObject.lastSentHeartbeatDate ??\n existingHeartbeatsObject.lastSentHeartbeatDate,\n heartbeats: [\n ...existingHeartbeatsObject.heartbeats,\n ...heartbeatsObject.heartbeats\n ]\n });\n }\n }\n}\n\n/**\n * Calculate bytes of a HeartbeatsByUserAgent array after being wrapped\n * in a platform logging header JSON object, stringified, and converted\n * to base 64.\n */\nexport function countBytes(heartbeatsCache: HeartbeatsByUserAgent[]): number {\n // base64 has a restricted set of characters, all of which should be 1 byte.\n return base64urlEncodeWithoutPadding(\n // heartbeatsCache wrapper properties\n JSON.stringify({ version: 2, heartbeats: heartbeatsCache })\n ).length;\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Component, ComponentType } from '@firebase/component';\nimport { PlatformLoggerServiceImpl } from './platformLoggerService';\nimport { name, version } from '../package.json';\nimport { _registerComponent } from './internal';\nimport { registerVersion } from './api';\nimport { HeartbeatServiceImpl } from './heartbeatService';\n\nexport function registerCoreComponents(variant?: string): void {\n _registerComponent(\n new Component(\n 'platform-logger',\n container => new PlatformLoggerServiceImpl(container),\n ComponentType.PRIVATE\n )\n );\n _registerComponent(\n new Component(\n 'heartbeat',\n container => new HeartbeatServiceImpl(container),\n ComponentType.PRIVATE\n )\n );\n\n // Register `app` package.\n registerVersion(name, version, variant);\n // BUILD_TARGET will be replaced by values like esm5, esm2017, cjs5, etc during the compilation\n registerVersion(name, version, '__BUILD_TARGET__');\n // Register platform SDK identifier (no version).\n registerVersion('fire-js', '');\n}\n", "/**\n * Firebase App\n *\n * @remarks This package coordinates the communication between the different Firebase components\n * @packageDocumentation\n */\n\n/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { registerCoreComponents } from './registerCoreComponents';\n\nexport * from './api';\nexport * from './internal';\nexport * from './public-types';\n\nregisterCoreComponents('__RUNTIME_ENV__');\n", "/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { registerVersion } from '@firebase/app';\nimport { name, version } from '../package.json';\n\nregisterVersion(name, version, 'app');\nexport * from '@firebase/app';\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { version } from '../../package.json';\n\nexport const PENDING_TIMEOUT_MS = 10000;\n\nexport const PACKAGE_VERSION = `w:${version}`;\nexport const INTERNAL_AUTH_VERSION = 'FIS_v2';\n\nexport const INSTALLATIONS_API_URL =\n 'https://firebaseinstallations.googleapis.com/v1';\n\nexport const TOKEN_EXPIRATION_BUFFER = 60 * 60 * 1000; // One hour\n\nexport const SERVICE = 'installations';\nexport const SERVICE_NAME = 'Installations';\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ErrorFactory, FirebaseError } from '@firebase/util';\nimport { SERVICE, SERVICE_NAME } from './constants';\n\nexport const enum ErrorCode {\n MISSING_APP_CONFIG_VALUES = 'missing-app-config-values',\n NOT_REGISTERED = 'not-registered',\n INSTALLATION_NOT_FOUND = 'installation-not-found',\n REQUEST_FAILED = 'request-failed',\n APP_OFFLINE = 'app-offline',\n DELETE_PENDING_REGISTRATION = 'delete-pending-registration'\n}\n\nconst ERROR_DESCRIPTION_MAP: { readonly [key in ErrorCode]: string } = {\n [ErrorCode.MISSING_APP_CONFIG_VALUES]:\n 'Missing App configuration value: \"{$valueName}\"',\n [ErrorCode.NOT_REGISTERED]: 'Firebase Installation is not registered.',\n [ErrorCode.INSTALLATION_NOT_FOUND]: 'Firebase Installation not found.',\n [ErrorCode.REQUEST_FAILED]:\n '{$requestName} request failed with error \"{$serverCode} {$serverStatus}: {$serverMessage}\"',\n [ErrorCode.APP_OFFLINE]: 'Could not process request. Application offline.',\n [ErrorCode.DELETE_PENDING_REGISTRATION]:\n \"Can't delete installation while there is a pending registration request.\"\n};\n\ninterface ErrorParams {\n [ErrorCode.MISSING_APP_CONFIG_VALUES]: {\n valueName: string;\n };\n [ErrorCode.REQUEST_FAILED]: {\n requestName: string;\n [index: string]: string | number; // to make Typescript 3.8 happy\n } & ServerErrorData;\n}\n\nexport const ERROR_FACTORY = new ErrorFactory(\n SERVICE,\n SERVICE_NAME,\n ERROR_DESCRIPTION_MAP\n);\n\nexport interface ServerErrorData {\n serverCode: number;\n serverMessage: string;\n serverStatus: string;\n}\n\nexport type ServerError = FirebaseError & { customData: ServerErrorData };\n\n/** Returns true if error is a FirebaseError that is based on an error from the server. */\nexport function isServerError(error: unknown): error is ServerError {\n return (\n error instanceof FirebaseError &&\n error.code.includes(ErrorCode.REQUEST_FAILED)\n );\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { FirebaseError } from '@firebase/util';\nimport { GenerateAuthTokenResponse } from '../interfaces/api-response';\nimport {\n CompletedAuthToken,\n RegisteredInstallationEntry,\n RequestStatus\n} from '../interfaces/installation-entry';\nimport {\n INSTALLATIONS_API_URL,\n INTERNAL_AUTH_VERSION\n} from '../util/constants';\nimport { ERROR_FACTORY, ErrorCode } from '../util/errors';\nimport { AppConfig } from '../interfaces/installation-impl';\n\nexport function getInstallationsEndpoint({ projectId }: AppConfig): string {\n return `${INSTALLATIONS_API_URL}/projects/${projectId}/installations`;\n}\n\nexport function extractAuthTokenInfoFromResponse(\n response: GenerateAuthTokenResponse\n): CompletedAuthToken {\n return {\n token: response.token,\n requestStatus: RequestStatus.COMPLETED,\n expiresIn: getExpiresInFromResponseExpiresIn(response.expiresIn),\n creationTime: Date.now()\n };\n}\n\nexport async function getErrorFromResponse(\n requestName: string,\n response: Response\n): Promise {\n const responseJson: ErrorResponse = await response.json();\n const errorData = responseJson.error;\n return ERROR_FACTORY.create(ErrorCode.REQUEST_FAILED, {\n requestName,\n serverCode: errorData.code,\n serverMessage: errorData.message,\n serverStatus: errorData.status\n });\n}\n\nexport function getHeaders({ apiKey }: AppConfig): Headers {\n return new Headers({\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n 'x-goog-api-key': apiKey\n });\n}\n\nexport function getHeadersWithAuth(\n appConfig: AppConfig,\n { refreshToken }: RegisteredInstallationEntry\n): Headers {\n const headers = getHeaders(appConfig);\n headers.append('Authorization', getAuthorizationHeader(refreshToken));\n return headers;\n}\n\nexport interface ErrorResponse {\n error: {\n code: number;\n message: string;\n status: string;\n };\n}\n\n/**\n * Calls the passed in fetch wrapper and returns the response.\n * If the returned response has a status of 5xx, re-runs the function once and\n * returns the response.\n */\nexport async function retryIfServerError(\n fn: () => Promise\n): Promise {\n const result = await fn();\n\n if (result.status >= 500 && result.status < 600) {\n // Internal Server Error. Retry request.\n return fn();\n }\n\n return result;\n}\n\nfunction getExpiresInFromResponseExpiresIn(responseExpiresIn: string): number {\n // This works because the server will never respond with fractions of a second.\n return Number(responseExpiresIn.replace('s', '000'));\n}\n\nfunction getAuthorizationHeader(refreshToken: string): string {\n return `${INTERNAL_AUTH_VERSION} ${refreshToken}`;\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { CreateInstallationResponse } from '../interfaces/api-response';\nimport {\n InProgressInstallationEntry,\n RegisteredInstallationEntry,\n RequestStatus\n} from '../interfaces/installation-entry';\nimport { INTERNAL_AUTH_VERSION, PACKAGE_VERSION } from '../util/constants';\nimport {\n extractAuthTokenInfoFromResponse,\n getErrorFromResponse,\n getHeaders,\n getInstallationsEndpoint,\n retryIfServerError\n} from './common';\nimport { FirebaseInstallationsImpl } from '../interfaces/installation-impl';\n\nexport async function createInstallationRequest(\n { appConfig, heartbeatServiceProvider }: FirebaseInstallationsImpl,\n { fid }: InProgressInstallationEntry\n): Promise {\n const endpoint = getInstallationsEndpoint(appConfig);\n\n const headers = getHeaders(appConfig);\n\n // If heartbeat service exists, add the heartbeat string to the header.\n const heartbeatService = heartbeatServiceProvider.getImmediate({\n optional: true\n });\n if (heartbeatService) {\n const heartbeatsHeader = await heartbeatService.getHeartbeatsHeader();\n if (heartbeatsHeader) {\n headers.append('x-firebase-client', heartbeatsHeader);\n }\n }\n\n const body = {\n fid,\n authVersion: INTERNAL_AUTH_VERSION,\n appId: appConfig.appId,\n sdkVersion: PACKAGE_VERSION\n };\n\n const request: RequestInit = {\n method: 'POST',\n headers,\n body: JSON.stringify(body)\n };\n\n const response = await retryIfServerError(() => fetch(endpoint, request));\n if (response.ok) {\n const responseValue: CreateInstallationResponse = await response.json();\n const registeredInstallationEntry: RegisteredInstallationEntry = {\n fid: responseValue.fid || fid,\n registrationStatus: RequestStatus.COMPLETED,\n refreshToken: responseValue.refreshToken,\n authToken: extractAuthTokenInfoFromResponse(responseValue.authToken)\n };\n return registeredInstallationEntry;\n } else {\n throw await getErrorFromResponse('Create Installation', response);\n }\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/** Returns a promise that resolves after given time passes. */\nexport function sleep(ms: number): Promise {\n return new Promise(resolve => {\n setTimeout(resolve, ms);\n });\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport function bufferToBase64UrlSafe(array: Uint8Array): string {\n const b64 = btoa(String.fromCharCode(...array));\n return b64.replace(/\\+/g, '-').replace(/\\//g, '_');\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { bufferToBase64UrlSafe } from './buffer-to-base64-url-safe';\n\nexport const VALID_FID_PATTERN = /^[cdef][\\w-]{21}$/;\nexport const INVALID_FID = '';\n\n/**\n * Generates a new FID using random values from Web Crypto API.\n * Returns an empty string if FID generation fails for any reason.\n */\nexport function generateFid(): string {\n try {\n // A valid FID has exactly 22 base64 characters, which is 132 bits, or 16.5\n // bytes. our implementation generates a 17 byte array instead.\n const fidByteArray = new Uint8Array(17);\n const crypto =\n self.crypto || (self as unknown as { msCrypto: Crypto }).msCrypto;\n crypto.getRandomValues(fidByteArray);\n\n // Replace the first 4 random bits with the constant FID header of 0b0111.\n fidByteArray[0] = 0b01110000 + (fidByteArray[0] % 0b00010000);\n\n const fid = encode(fidByteArray);\n\n return VALID_FID_PATTERN.test(fid) ? fid : INVALID_FID;\n } catch {\n // FID generation errored\n return INVALID_FID;\n }\n}\n\n/** Converts a FID Uint8Array to a base64 string representation. */\nfunction encode(fidByteArray: Uint8Array): string {\n const b64String = bufferToBase64UrlSafe(fidByteArray);\n\n // Remove the 23rd character that was added because of the extra 4 bits at the\n // end of our 17 byte array, and the '=' padding.\n return b64String.substr(0, 22);\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { AppConfig } from '../interfaces/installation-impl';\n\n/** Returns a string key that can be used to identify the app. */\nexport function getKey(appConfig: AppConfig): string {\n return `${appConfig.appName}!${appConfig.appId}`;\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { getKey } from '../util/get-key';\nimport { AppConfig } from '../interfaces/installation-impl';\nimport { IdChangeCallbackFn } from '../api';\n\nconst fidChangeCallbacks: Map> = new Map();\n\n/**\n * Calls the onIdChange callbacks with the new FID value, and broadcasts the\n * change to other tabs.\n */\nexport function fidChanged(appConfig: AppConfig, fid: string): void {\n const key = getKey(appConfig);\n\n callFidChangeCallbacks(key, fid);\n broadcastFidChange(key, fid);\n}\n\nexport function addCallback(\n appConfig: AppConfig,\n callback: IdChangeCallbackFn\n): void {\n // Open the broadcast channel if it's not already open,\n // to be able to listen to change events from other tabs.\n getBroadcastChannel();\n\n const key = getKey(appConfig);\n\n let callbackSet = fidChangeCallbacks.get(key);\n if (!callbackSet) {\n callbackSet = new Set();\n fidChangeCallbacks.set(key, callbackSet);\n }\n callbackSet.add(callback);\n}\n\nexport function removeCallback(\n appConfig: AppConfig,\n callback: IdChangeCallbackFn\n): void {\n const key = getKey(appConfig);\n\n const callbackSet = fidChangeCallbacks.get(key);\n\n if (!callbackSet) {\n return;\n }\n\n callbackSet.delete(callback);\n if (callbackSet.size === 0) {\n fidChangeCallbacks.delete(key);\n }\n\n // Close broadcast channel if there are no more callbacks.\n closeBroadcastChannel();\n}\n\nfunction callFidChangeCallbacks(key: string, fid: string): void {\n const callbacks = fidChangeCallbacks.get(key);\n if (!callbacks) {\n return;\n }\n\n for (const callback of callbacks) {\n callback(fid);\n }\n}\n\nfunction broadcastFidChange(key: string, fid: string): void {\n const channel = getBroadcastChannel();\n if (channel) {\n channel.postMessage({ key, fid });\n }\n closeBroadcastChannel();\n}\n\nlet broadcastChannel: BroadcastChannel | null = null;\n/** Opens and returns a BroadcastChannel if it is supported by the browser. */\nfunction getBroadcastChannel(): BroadcastChannel | null {\n if (!broadcastChannel && 'BroadcastChannel' in self) {\n broadcastChannel = new BroadcastChannel('[Firebase] FID Change');\n broadcastChannel.onmessage = e => {\n callFidChangeCallbacks(e.data.key, e.data.fid);\n };\n }\n return broadcastChannel;\n}\n\nfunction closeBroadcastChannel(): void {\n if (fidChangeCallbacks.size === 0 && broadcastChannel) {\n broadcastChannel.close();\n broadcastChannel = null;\n }\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { DBSchema, IDBPDatabase, openDB } from 'idb';\nimport { AppConfig } from '../interfaces/installation-impl';\nimport { InstallationEntry } from '../interfaces/installation-entry';\nimport { getKey } from '../util/get-key';\nimport { fidChanged } from './fid-changed';\n\nconst DATABASE_NAME = 'firebase-installations-database';\nconst DATABASE_VERSION = 1;\nconst OBJECT_STORE_NAME = 'firebase-installations-store';\n\ninterface InstallationsDB extends DBSchema {\n 'firebase-installations-store': {\n key: string;\n value: InstallationEntry | undefined;\n };\n}\n\nlet dbPromise: Promise> | null = null;\nfunction getDbPromise(): Promise> {\n if (!dbPromise) {\n dbPromise = openDB(DATABASE_NAME, DATABASE_VERSION, {\n upgrade: (db, oldVersion) => {\n // We don't use 'break' in this switch statement, the fall-through\n // behavior is what we want, because if there are multiple versions between\n // the old version and the current version, we want ALL the migrations\n // that correspond to those versions to run, not only the last one.\n // eslint-disable-next-line default-case\n switch (oldVersion) {\n case 0:\n db.createObjectStore(OBJECT_STORE_NAME);\n }\n }\n });\n }\n return dbPromise;\n}\n\n/** Gets record(s) from the objectStore that match the given key. */\nexport async function get(\n appConfig: AppConfig\n): Promise {\n const key = getKey(appConfig);\n const db = await getDbPromise();\n return db\n .transaction(OBJECT_STORE_NAME)\n .objectStore(OBJECT_STORE_NAME)\n .get(key) as Promise;\n}\n\n/** Assigns or overwrites the record for the given key with the given value. */\nexport async function set(\n appConfig: AppConfig,\n value: ValueType\n): Promise {\n const key = getKey(appConfig);\n const db = await getDbPromise();\n const tx = db.transaction(OBJECT_STORE_NAME, 'readwrite');\n const objectStore = tx.objectStore(OBJECT_STORE_NAME);\n const oldValue = (await objectStore.get(key)) as InstallationEntry;\n await objectStore.put(value, key);\n await tx.done;\n\n if (!oldValue || oldValue.fid !== value.fid) {\n fidChanged(appConfig, value.fid);\n }\n\n return value;\n}\n\n/** Removes record(s) from the objectStore that match the given key. */\nexport async function remove(appConfig: AppConfig): Promise {\n const key = getKey(appConfig);\n const db = await getDbPromise();\n const tx = db.transaction(OBJECT_STORE_NAME, 'readwrite');\n await tx.objectStore(OBJECT_STORE_NAME).delete(key);\n await tx.done;\n}\n\n/**\n * Atomically updates a record with the result of updateFn, which gets\n * called with the current value. If newValue is undefined, the record is\n * deleted instead.\n * @return Updated value\n */\nexport async function update(\n appConfig: AppConfig,\n updateFn: (previousValue: InstallationEntry | undefined) => ValueType\n): Promise {\n const key = getKey(appConfig);\n const db = await getDbPromise();\n const tx = db.transaction(OBJECT_STORE_NAME, 'readwrite');\n const store = tx.objectStore(OBJECT_STORE_NAME);\n const oldValue: InstallationEntry | undefined = (await store.get(\n key\n )) as InstallationEntry;\n const newValue = updateFn(oldValue);\n\n if (newValue === undefined) {\n await store.delete(key);\n } else {\n await store.put(newValue, key);\n }\n await tx.done;\n\n if (newValue && (!oldValue || oldValue.fid !== newValue.fid)) {\n fidChanged(appConfig, newValue.fid);\n }\n\n return newValue;\n}\n\nexport async function clear(): Promise {\n const db = await getDbPromise();\n const tx = db.transaction(OBJECT_STORE_NAME, 'readwrite');\n await tx.objectStore(OBJECT_STORE_NAME).clear();\n await tx.done;\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { createInstallationRequest } from '../functions/create-installation-request';\nimport {\n AppConfig,\n FirebaseInstallationsImpl\n} from '../interfaces/installation-impl';\nimport {\n InProgressInstallationEntry,\n InstallationEntry,\n RegisteredInstallationEntry,\n RequestStatus\n} from '../interfaces/installation-entry';\nimport { PENDING_TIMEOUT_MS } from '../util/constants';\nimport { ERROR_FACTORY, ErrorCode, isServerError } from '../util/errors';\nimport { sleep } from '../util/sleep';\nimport { generateFid, INVALID_FID } from './generate-fid';\nimport { remove, set, update } from './idb-manager';\n\nexport interface InstallationEntryWithRegistrationPromise {\n installationEntry: InstallationEntry;\n /** Exist iff the installationEntry is not registered. */\n registrationPromise?: Promise;\n}\n\n/**\n * Updates and returns the InstallationEntry from the database.\n * Also triggers a registration request if it is necessary and possible.\n */\nexport async function getInstallationEntry(\n installations: FirebaseInstallationsImpl\n): Promise {\n let registrationPromise: Promise | undefined;\n\n const installationEntry = await update(installations.appConfig, oldEntry => {\n const installationEntry = updateOrCreateInstallationEntry(oldEntry);\n const entryWithPromise = triggerRegistrationIfNecessary(\n installations,\n installationEntry\n );\n registrationPromise = entryWithPromise.registrationPromise;\n return entryWithPromise.installationEntry;\n });\n\n if (installationEntry.fid === INVALID_FID) {\n // FID generation failed. Waiting for the FID from the server.\n return { installationEntry: await registrationPromise! };\n }\n\n return {\n installationEntry,\n registrationPromise\n };\n}\n\n/**\n * Creates a new Installation Entry if one does not exist.\n * Also clears timed out pending requests.\n */\nfunction updateOrCreateInstallationEntry(\n oldEntry: InstallationEntry | undefined\n): InstallationEntry {\n const entry: InstallationEntry = oldEntry || {\n fid: generateFid(),\n registrationStatus: RequestStatus.NOT_STARTED\n };\n\n return clearTimedOutRequest(entry);\n}\n\n/**\n * If the Firebase Installation is not registered yet, this will trigger the\n * registration and return an InProgressInstallationEntry.\n *\n * If registrationPromise does not exist, the installationEntry is guaranteed\n * to be registered.\n */\nfunction triggerRegistrationIfNecessary(\n installations: FirebaseInstallationsImpl,\n installationEntry: InstallationEntry\n): InstallationEntryWithRegistrationPromise {\n if (installationEntry.registrationStatus === RequestStatus.NOT_STARTED) {\n if (!navigator.onLine) {\n // Registration required but app is offline.\n const registrationPromiseWithError = Promise.reject(\n ERROR_FACTORY.create(ErrorCode.APP_OFFLINE)\n );\n return {\n installationEntry,\n registrationPromise: registrationPromiseWithError\n };\n }\n\n // Try registering. Change status to IN_PROGRESS.\n const inProgressEntry: InProgressInstallationEntry = {\n fid: installationEntry.fid,\n registrationStatus: RequestStatus.IN_PROGRESS,\n registrationTime: Date.now()\n };\n const registrationPromise = registerInstallation(\n installations,\n inProgressEntry\n );\n return { installationEntry: inProgressEntry, registrationPromise };\n } else if (\n installationEntry.registrationStatus === RequestStatus.IN_PROGRESS\n ) {\n return {\n installationEntry,\n registrationPromise: waitUntilFidRegistration(installations)\n };\n } else {\n return { installationEntry };\n }\n}\n\n/** This will be executed only once for each new Firebase Installation. */\nasync function registerInstallation(\n installations: FirebaseInstallationsImpl,\n installationEntry: InProgressInstallationEntry\n): Promise {\n try {\n const registeredInstallationEntry = await createInstallationRequest(\n installations,\n installationEntry\n );\n return set(installations.appConfig, registeredInstallationEntry);\n } catch (e) {\n if (isServerError(e) && e.customData.serverCode === 409) {\n // Server returned a \"FID can not be used\" error.\n // Generate a new ID next time.\n await remove(installations.appConfig);\n } else {\n // Registration failed. Set FID as not registered.\n await set(installations.appConfig, {\n fid: installationEntry.fid,\n registrationStatus: RequestStatus.NOT_STARTED\n });\n }\n throw e;\n }\n}\n\n/** Call if FID registration is pending in another request. */\nasync function waitUntilFidRegistration(\n installations: FirebaseInstallationsImpl\n): Promise {\n // Unfortunately, there is no way of reliably observing when a value in\n // IndexedDB changes (yet, see https://github.com/WICG/indexed-db-observers),\n // so we need to poll.\n\n let entry: InstallationEntry = await updateInstallationRequest(\n installations.appConfig\n );\n while (entry.registrationStatus === RequestStatus.IN_PROGRESS) {\n // createInstallation request still in progress.\n await sleep(100);\n\n entry = await updateInstallationRequest(installations.appConfig);\n }\n\n if (entry.registrationStatus === RequestStatus.NOT_STARTED) {\n // The request timed out or failed in a different call. Try again.\n const { installationEntry, registrationPromise } =\n await getInstallationEntry(installations);\n\n if (registrationPromise) {\n return registrationPromise;\n } else {\n // if there is no registrationPromise, entry is registered.\n return installationEntry as RegisteredInstallationEntry;\n }\n }\n\n return entry;\n}\n\n/**\n * Called only if there is a CreateInstallation request in progress.\n *\n * Updates the InstallationEntry in the DB based on the status of the\n * CreateInstallation request.\n *\n * Returns the updated InstallationEntry.\n */\nfunction updateInstallationRequest(\n appConfig: AppConfig\n): Promise {\n return update(appConfig, oldEntry => {\n if (!oldEntry) {\n throw ERROR_FACTORY.create(ErrorCode.INSTALLATION_NOT_FOUND);\n }\n return clearTimedOutRequest(oldEntry);\n });\n}\n\nfunction clearTimedOutRequest(entry: InstallationEntry): InstallationEntry {\n if (hasInstallationRequestTimedOut(entry)) {\n return {\n fid: entry.fid,\n registrationStatus: RequestStatus.NOT_STARTED\n };\n }\n\n return entry;\n}\n\nfunction hasInstallationRequestTimedOut(\n installationEntry: InstallationEntry\n): boolean {\n return (\n installationEntry.registrationStatus === RequestStatus.IN_PROGRESS &&\n installationEntry.registrationTime + PENDING_TIMEOUT_MS < Date.now()\n );\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { GenerateAuthTokenResponse } from '../interfaces/api-response';\nimport {\n CompletedAuthToken,\n RegisteredInstallationEntry\n} from '../interfaces/installation-entry';\nimport { PACKAGE_VERSION } from '../util/constants';\nimport {\n extractAuthTokenInfoFromResponse,\n getErrorFromResponse,\n getHeadersWithAuth,\n getInstallationsEndpoint,\n retryIfServerError\n} from './common';\nimport {\n FirebaseInstallationsImpl,\n AppConfig\n} from '../interfaces/installation-impl';\n\nexport async function generateAuthTokenRequest(\n { appConfig, heartbeatServiceProvider }: FirebaseInstallationsImpl,\n installationEntry: RegisteredInstallationEntry\n): Promise {\n const endpoint = getGenerateAuthTokenEndpoint(appConfig, installationEntry);\n\n const headers = getHeadersWithAuth(appConfig, installationEntry);\n\n // If heartbeat service exists, add the heartbeat string to the header.\n const heartbeatService = heartbeatServiceProvider.getImmediate({\n optional: true\n });\n if (heartbeatService) {\n const heartbeatsHeader = await heartbeatService.getHeartbeatsHeader();\n if (heartbeatsHeader) {\n headers.append('x-firebase-client', heartbeatsHeader);\n }\n }\n\n const body = {\n installation: {\n sdkVersion: PACKAGE_VERSION,\n appId: appConfig.appId\n }\n };\n\n const request: RequestInit = {\n method: 'POST',\n headers,\n body: JSON.stringify(body)\n };\n\n const response = await retryIfServerError(() => fetch(endpoint, request));\n if (response.ok) {\n const responseValue: GenerateAuthTokenResponse = await response.json();\n const completedAuthToken: CompletedAuthToken =\n extractAuthTokenInfoFromResponse(responseValue);\n return completedAuthToken;\n } else {\n throw await getErrorFromResponse('Generate Auth Token', response);\n }\n}\n\nfunction getGenerateAuthTokenEndpoint(\n appConfig: AppConfig,\n { fid }: RegisteredInstallationEntry\n): string {\n return `${getInstallationsEndpoint(appConfig)}/${fid}/authTokens:generate`;\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { generateAuthTokenRequest } from '../functions/generate-auth-token-request';\nimport {\n AppConfig,\n FirebaseInstallationsImpl\n} from '../interfaces/installation-impl';\nimport {\n AuthToken,\n CompletedAuthToken,\n InProgressAuthToken,\n InstallationEntry,\n RegisteredInstallationEntry,\n RequestStatus\n} from '../interfaces/installation-entry';\nimport { PENDING_TIMEOUT_MS, TOKEN_EXPIRATION_BUFFER } from '../util/constants';\nimport { ERROR_FACTORY, ErrorCode, isServerError } from '../util/errors';\nimport { sleep } from '../util/sleep';\nimport { remove, set, update } from './idb-manager';\n\n/**\n * Returns a valid authentication token for the installation. Generates a new\n * token if one doesn't exist, is expired or about to expire.\n *\n * Should only be called if the Firebase Installation is registered.\n */\nexport async function refreshAuthToken(\n installations: FirebaseInstallationsImpl,\n forceRefresh = false\n): Promise {\n let tokenPromise: Promise | undefined;\n const entry = await update(installations.appConfig, oldEntry => {\n if (!isEntryRegistered(oldEntry)) {\n throw ERROR_FACTORY.create(ErrorCode.NOT_REGISTERED);\n }\n\n const oldAuthToken = oldEntry.authToken;\n if (!forceRefresh && isAuthTokenValid(oldAuthToken)) {\n // There is a valid token in the DB.\n return oldEntry;\n } else if (oldAuthToken.requestStatus === RequestStatus.IN_PROGRESS) {\n // There already is a token request in progress.\n tokenPromise = waitUntilAuthTokenRequest(installations, forceRefresh);\n return oldEntry;\n } else {\n // No token or token expired.\n if (!navigator.onLine) {\n throw ERROR_FACTORY.create(ErrorCode.APP_OFFLINE);\n }\n\n const inProgressEntry = makeAuthTokenRequestInProgressEntry(oldEntry);\n tokenPromise = fetchAuthTokenFromServer(installations, inProgressEntry);\n return inProgressEntry;\n }\n });\n\n const authToken = tokenPromise\n ? await tokenPromise\n : (entry.authToken as CompletedAuthToken);\n return authToken;\n}\n\n/**\n * Call only if FID is registered and Auth Token request is in progress.\n *\n * Waits until the current pending request finishes. If the request times out,\n * tries once in this thread as well.\n */\nasync function waitUntilAuthTokenRequest(\n installations: FirebaseInstallationsImpl,\n forceRefresh: boolean\n): Promise {\n // Unfortunately, there is no way of reliably observing when a value in\n // IndexedDB changes (yet, see https://github.com/WICG/indexed-db-observers),\n // so we need to poll.\n\n let entry = await updateAuthTokenRequest(installations.appConfig);\n while (entry.authToken.requestStatus === RequestStatus.IN_PROGRESS) {\n // generateAuthToken still in progress.\n await sleep(100);\n\n entry = await updateAuthTokenRequest(installations.appConfig);\n }\n\n const authToken = entry.authToken;\n if (authToken.requestStatus === RequestStatus.NOT_STARTED) {\n // The request timed out or failed in a different call. Try again.\n return refreshAuthToken(installations, forceRefresh);\n } else {\n return authToken;\n }\n}\n\n/**\n * Called only if there is a GenerateAuthToken request in progress.\n *\n * Updates the InstallationEntry in the DB based on the status of the\n * GenerateAuthToken request.\n *\n * Returns the updated InstallationEntry.\n */\nfunction updateAuthTokenRequest(\n appConfig: AppConfig\n): Promise {\n return update(appConfig, oldEntry => {\n if (!isEntryRegistered(oldEntry)) {\n throw ERROR_FACTORY.create(ErrorCode.NOT_REGISTERED);\n }\n\n const oldAuthToken = oldEntry.authToken;\n if (hasAuthTokenRequestTimedOut(oldAuthToken)) {\n return {\n ...oldEntry,\n authToken: { requestStatus: RequestStatus.NOT_STARTED }\n };\n }\n\n return oldEntry;\n });\n}\n\nasync function fetchAuthTokenFromServer(\n installations: FirebaseInstallationsImpl,\n installationEntry: RegisteredInstallationEntry\n): Promise {\n try {\n const authToken = await generateAuthTokenRequest(\n installations,\n installationEntry\n );\n const updatedInstallationEntry: RegisteredInstallationEntry = {\n ...installationEntry,\n authToken\n };\n await set(installations.appConfig, updatedInstallationEntry);\n return authToken;\n } catch (e) {\n if (\n isServerError(e) &&\n (e.customData.serverCode === 401 || e.customData.serverCode === 404)\n ) {\n // Server returned a \"FID not found\" or a \"Invalid authentication\" error.\n // Generate a new ID next time.\n await remove(installations.appConfig);\n } else {\n const updatedInstallationEntry: RegisteredInstallationEntry = {\n ...installationEntry,\n authToken: { requestStatus: RequestStatus.NOT_STARTED }\n };\n await set(installations.appConfig, updatedInstallationEntry);\n }\n throw e;\n }\n}\n\nfunction isEntryRegistered(\n installationEntry: InstallationEntry | undefined\n): installationEntry is RegisteredInstallationEntry {\n return (\n installationEntry !== undefined &&\n installationEntry.registrationStatus === RequestStatus.COMPLETED\n );\n}\n\nfunction isAuthTokenValid(authToken: AuthToken): boolean {\n return (\n authToken.requestStatus === RequestStatus.COMPLETED &&\n !isAuthTokenExpired(authToken)\n );\n}\n\nfunction isAuthTokenExpired(authToken: CompletedAuthToken): boolean {\n const now = Date.now();\n return (\n now < authToken.creationTime ||\n authToken.creationTime + authToken.expiresIn < now + TOKEN_EXPIRATION_BUFFER\n );\n}\n\n/** Returns an updated InstallationEntry with an InProgressAuthToken. */\nfunction makeAuthTokenRequestInProgressEntry(\n oldEntry: RegisteredInstallationEntry\n): RegisteredInstallationEntry {\n const inProgressAuthToken: InProgressAuthToken = {\n requestStatus: RequestStatus.IN_PROGRESS,\n requestTime: Date.now()\n };\n return {\n ...oldEntry,\n authToken: inProgressAuthToken\n };\n}\n\nfunction hasAuthTokenRequestTimedOut(authToken: AuthToken): boolean {\n return (\n authToken.requestStatus === RequestStatus.IN_PROGRESS &&\n authToken.requestTime + PENDING_TIMEOUT_MS < Date.now()\n );\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { getInstallationEntry } from '../helpers/get-installation-entry';\nimport { refreshAuthToken } from '../helpers/refresh-auth-token';\nimport { FirebaseInstallationsImpl } from '../interfaces/installation-impl';\nimport { Installations } from '../interfaces/public-types';\n\n/**\n * Creates a Firebase Installation if there isn't one for the app and\n * returns the Installation ID.\n * @param installations - The `Installations` instance.\n *\n * @public\n */\nexport async function getId(installations: Installations): Promise {\n const installationsImpl = installations as FirebaseInstallationsImpl;\n const { installationEntry, registrationPromise } = await getInstallationEntry(\n installationsImpl\n );\n\n if (registrationPromise) {\n registrationPromise.catch(console.error);\n } else {\n // If the installation is already registered, update the authentication\n // token if needed.\n refreshAuthToken(installationsImpl).catch(console.error);\n }\n\n return installationEntry.fid;\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { getInstallationEntry } from '../helpers/get-installation-entry';\nimport { refreshAuthToken } from '../helpers/refresh-auth-token';\nimport { FirebaseInstallationsImpl } from '../interfaces/installation-impl';\nimport { Installations } from '../interfaces/public-types';\n\n/**\n * Returns a Firebase Installations auth token, identifying the current\n * Firebase Installation.\n * @param installations - The `Installations` instance.\n * @param forceRefresh - Force refresh regardless of token expiration.\n *\n * @public\n */\nexport async function getToken(\n installations: Installations,\n forceRefresh = false\n): Promise {\n const installationsImpl = installations as FirebaseInstallationsImpl;\n await completeInstallationRegistration(installationsImpl);\n\n // At this point we either have a Registered Installation in the DB, or we've\n // already thrown an error.\n const authToken = await refreshAuthToken(installationsImpl, forceRefresh);\n return authToken.token;\n}\n\nasync function completeInstallationRegistration(\n installations: FirebaseInstallationsImpl\n): Promise {\n const { registrationPromise } = await getInstallationEntry(installations);\n\n if (registrationPromise) {\n // A createInstallation request is in progress. Wait until it finishes.\n await registrationPromise;\n }\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { AppConfig } from '../interfaces/installation-impl';\nimport { RegisteredInstallationEntry } from '../interfaces/installation-entry';\nimport {\n getErrorFromResponse,\n getHeadersWithAuth,\n getInstallationsEndpoint,\n retryIfServerError\n} from './common';\n\nexport async function deleteInstallationRequest(\n appConfig: AppConfig,\n installationEntry: RegisteredInstallationEntry\n): Promise {\n const endpoint = getDeleteEndpoint(appConfig, installationEntry);\n\n const headers = getHeadersWithAuth(appConfig, installationEntry);\n const request: RequestInit = {\n method: 'DELETE',\n headers\n };\n\n const response = await retryIfServerError(() => fetch(endpoint, request));\n if (!response.ok) {\n throw await getErrorFromResponse('Delete Installation', response);\n }\n}\n\nfunction getDeleteEndpoint(\n appConfig: AppConfig,\n { fid }: RegisteredInstallationEntry\n): string {\n return `${getInstallationsEndpoint(appConfig)}/${fid}`;\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { deleteInstallationRequest } from '../functions/delete-installation-request';\nimport { remove, update } from '../helpers/idb-manager';\nimport { RequestStatus } from '../interfaces/installation-entry';\nimport { ERROR_FACTORY, ErrorCode } from '../util/errors';\nimport { FirebaseInstallationsImpl } from '../interfaces/installation-impl';\nimport { Installations } from '../interfaces/public-types';\n\n/**\n * Deletes the Firebase Installation and all associated data.\n * @param installations - The `Installations` instance.\n *\n * @public\n */\nexport async function deleteInstallations(\n installations: Installations\n): Promise {\n const { appConfig } = installations as FirebaseInstallationsImpl;\n\n const entry = await update(appConfig, oldEntry => {\n if (oldEntry && oldEntry.registrationStatus === RequestStatus.NOT_STARTED) {\n // Delete the unregistered entry without sending a deleteInstallation request.\n return undefined;\n }\n return oldEntry;\n });\n\n if (entry) {\n if (entry.registrationStatus === RequestStatus.IN_PROGRESS) {\n // Can't delete while trying to register.\n throw ERROR_FACTORY.create(ErrorCode.DELETE_PENDING_REGISTRATION);\n } else if (entry.registrationStatus === RequestStatus.COMPLETED) {\n if (!navigator.onLine) {\n throw ERROR_FACTORY.create(ErrorCode.APP_OFFLINE);\n } else {\n await deleteInstallationRequest(appConfig, entry);\n await remove(appConfig);\n }\n }\n }\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { addCallback, removeCallback } from '../helpers/fid-changed';\nimport { FirebaseInstallationsImpl } from '../interfaces/installation-impl';\nimport { Installations } from '../interfaces/public-types';\n\n/**\n * An user defined callback function that gets called when Installations ID changes.\n *\n * @public\n */\nexport type IdChangeCallbackFn = (installationId: string) => void;\n/**\n * Unsubscribe a callback function previously added via {@link IdChangeCallbackFn}.\n *\n * @public\n */\nexport type IdChangeUnsubscribeFn = () => void;\n\n/**\n * Sets a new callback that will get called when Installation ID changes.\n * Returns an unsubscribe function that will remove the callback when called.\n * @param installations - The `Installations` instance.\n * @param callback - The callback function that is invoked when FID changes.\n * @returns A function that can be called to unsubscribe.\n *\n * @public\n */\nexport function onIdChange(\n installations: Installations,\n callback: IdChangeCallbackFn\n): IdChangeUnsubscribeFn {\n const { appConfig } = installations as FirebaseInstallationsImpl;\n\n addCallback(appConfig, callback);\n return () => {\n removeCallback(appConfig, callback);\n };\n}\n", "/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { FirebaseApp, getApp, _getProvider } from '@firebase/app';\nimport { Installations } from '../interfaces/public-types';\n\n/**\n * Returns an instance of {@link Installations} associated with the given\n * {@link @firebase/app#FirebaseApp} instance.\n * @param app - The {@link @firebase/app#FirebaseApp} instance.\n *\n * @public\n */\nexport function getInstallations(app: FirebaseApp = getApp()): Installations {\n const installationsImpl = _getProvider(app, 'installations').getImmediate();\n return installationsImpl;\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { FirebaseApp, FirebaseOptions } from '@firebase/app';\nimport { FirebaseError } from '@firebase/util';\nimport { AppConfig } from '../interfaces/installation-impl';\nimport { ERROR_FACTORY, ErrorCode } from '../util/errors';\n\nexport function extractAppConfig(app: FirebaseApp): AppConfig {\n if (!app || !app.options) {\n throw getMissingValueError('App Configuration');\n }\n\n if (!app.name) {\n throw getMissingValueError('App Name');\n }\n\n // Required app config keys\n const configKeys: Array = [\n 'projectId',\n 'apiKey',\n 'appId'\n ];\n\n for (const keyName of configKeys) {\n if (!app.options[keyName]) {\n throw getMissingValueError(keyName);\n }\n }\n\n return {\n appName: app.name,\n projectId: app.options.projectId!,\n apiKey: app.options.apiKey!,\n appId: app.options.appId!\n };\n}\n\nfunction getMissingValueError(valueName: string): FirebaseError {\n return ERROR_FACTORY.create(ErrorCode.MISSING_APP_CONFIG_VALUES, {\n valueName\n });\n}\n", "/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { _registerComponent, _getProvider } from '@firebase/app';\nimport {\n Component,\n ComponentType,\n InstanceFactory,\n ComponentContainer\n} from '@firebase/component';\nimport { getId, getToken } from '../api/index';\nimport { _FirebaseInstallationsInternal } from '../interfaces/public-types';\nimport { FirebaseInstallationsImpl } from '../interfaces/installation-impl';\nimport { extractAppConfig } from '../helpers/extract-app-config';\n\nconst INSTALLATIONS_NAME = 'installations';\nconst INSTALLATIONS_NAME_INTERNAL = 'installations-internal';\n\nconst publicFactory: InstanceFactory<'installations'> = (\n container: ComponentContainer\n) => {\n const app = container.getProvider('app').getImmediate();\n // Throws if app isn't configured properly.\n const appConfig = extractAppConfig(app);\n const heartbeatServiceProvider = _getProvider(app, 'heartbeat');\n\n const installationsImpl: FirebaseInstallationsImpl = {\n app,\n appConfig,\n heartbeatServiceProvider,\n _delete: () => Promise.resolve()\n };\n return installationsImpl;\n};\n\nconst internalFactory: InstanceFactory<'installations-internal'> = (\n container: ComponentContainer\n) => {\n const app = container.getProvider('app').getImmediate();\n // Internal FIS instance relies on public FIS instance.\n const installations = _getProvider(app, INSTALLATIONS_NAME).getImmediate();\n\n const installationsInternal: _FirebaseInstallationsInternal = {\n getId: () => getId(installations),\n getToken: (forceRefresh?: boolean) => getToken(installations, forceRefresh)\n };\n return installationsInternal;\n};\n\nexport function registerInstallations(): void {\n _registerComponent(\n new Component(INSTALLATIONS_NAME, publicFactory, ComponentType.PUBLIC)\n );\n _registerComponent(\n new Component(\n INSTALLATIONS_NAME_INTERNAL,\n internalFactory,\n ComponentType.PRIVATE\n )\n );\n}\n", "/**\n * Firebase Installations\n *\n * @packageDocumentation\n */\n\n/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { registerInstallations } from './functions/config';\nimport { registerVersion } from '@firebase/app';\nimport { name, version } from '../package.json';\n\nexport * from './api';\nexport * from './interfaces/public-types';\n\nregisterInstallations();\nregisterVersion(name, version);\n// BUILD_TARGET will be replaced by values like esm5, esm2017, cjs5, etc during the compilation\nregisterVersion(name, version, '__BUILD_TARGET__');\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport const DEFAULT_SW_PATH = '/firebase-messaging-sw.js';\nexport const DEFAULT_SW_SCOPE = '/firebase-cloud-messaging-push-scope';\n\nexport const DEFAULT_VAPID_KEY =\n 'BDOU99-h67HcA6JeFXHbSNMu7e2yNNu3RzoMj8TM4W88jITfq7ZmPvIM1Iv-4_l2LxQcYwhqby2xGpWwzjfAnG4';\n\nexport const ENDPOINT = 'https://fcmregistrations.googleapis.com/v1';\n\n/** Key of FCM Payload in Notification's data field. */\nexport const FCM_MSG = 'FCM_MSG';\n\nexport const CONSOLE_CAMPAIGN_ID = 'google.c.a.c_id';\nexport const CONSOLE_CAMPAIGN_NAME = 'google.c.a.c_l';\nexport const CONSOLE_CAMPAIGN_TIME = 'google.c.a.ts';\n/** Set to '1' if Analytics is enabled for the campaign */\nexport const CONSOLE_CAMPAIGN_ANALYTICS_ENABLED = 'google.c.a.e';\nexport const TAG = 'FirebaseMessaging: ';\nexport const MAX_NUMBER_OF_EVENTS_PER_LOG_REQUEST = 1000;\nexport const MAX_RETRIES = 3;\nexport const LOG_INTERVAL_IN_MS = 86400000; //24 hour\nexport const DEFAULT_BACKOFF_TIME_MS = 5000;\n\n// FCM log source name registered at Firelog: 'FCM_CLIENT_EVENT_LOGGING'. It uniquely identifies\n// FCM's logging configuration.\nexport const FCM_LOG_SOURCE = 1249;\n\n// Defined as in proto/messaging_event.proto. Neglecting fields that are supported.\nexport const SDK_PLATFORM_WEB = 3;\nexport const EVENT_MESSAGE_DELIVERED = 1;\n\nexport enum MessageType {\n DATA_MESSAGE = 1,\n DISPLAY_NOTIFICATION = 3\n}\n", "/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License. You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under the License\n * is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n * or implied. See the License for the specific language governing permissions and limitations under\n * the License.\n */\n\nimport {\n CONSOLE_CAMPAIGN_ANALYTICS_ENABLED,\n CONSOLE_CAMPAIGN_ID,\n CONSOLE_CAMPAIGN_NAME,\n CONSOLE_CAMPAIGN_TIME\n} from '../util/constants';\n\nexport interface MessagePayloadInternal {\n notification?: NotificationPayloadInternal;\n data?: unknown;\n fcmOptions?: FcmOptionsInternal;\n messageType?: MessageType;\n isFirebaseMessaging?: boolean;\n from: string;\n fcmMessageId: string;\n // eslint-disable-next-line camelcase\n collapse_key: string;\n}\n\nexport interface NotificationPayloadInternal extends NotificationOptions {\n title: string;\n // Supported in the Legacy Send API.\n // See:https://firebase.google.com/docs/cloud-messaging/xmpp-server-ref.\n // eslint-disable-next-line camelcase\n click_action?: string;\n}\n\n// Defined in\n// https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages#webpushfcmoptions. Note\n// that the keys are sent to the clients in snake cases which we need to convert to camel so it can\n// be exposed as a type to match the Firebase API convention.\nexport interface FcmOptionsInternal {\n link?: string;\n\n // eslint-disable-next-line camelcase\n analytics_label?: string;\n}\n\nexport enum MessageType {\n PUSH_RECEIVED = 'push-received',\n NOTIFICATION_CLICKED = 'notification-clicked'\n}\n\n/** Additional data of a message sent from the FN Console. */\nexport interface ConsoleMessageData {\n [CONSOLE_CAMPAIGN_ID]: string;\n [CONSOLE_CAMPAIGN_TIME]: string;\n [CONSOLE_CAMPAIGN_NAME]?: string;\n [CONSOLE_CAMPAIGN_ANALYTICS_ENABLED]?: '1';\n}\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport function arrayToBase64(array: Uint8Array | ArrayBuffer): string {\n const uint8Array = new Uint8Array(array);\n const base64String = btoa(String.fromCharCode(...uint8Array));\n return base64String.replace(/=/g, '').replace(/\\+/g, '-').replace(/\\//g, '_');\n}\n\nexport function base64ToArray(base64String: string): Uint8Array {\n const padding = '='.repeat((4 - (base64String.length % 4)) % 4);\n const base64 = (base64String + padding)\n .replace(/\\-/g, '+')\n .replace(/_/g, '/');\n\n const rawData = atob(base64);\n const outputArray = new Uint8Array(rawData.length);\n\n for (let i = 0; i < rawData.length; ++i) {\n outputArray[i] = rawData.charCodeAt(i);\n }\n return outputArray;\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { deleteDB, openDB } from 'idb';\n\nimport { TokenDetails } from '../interfaces/token-details';\nimport { arrayToBase64 } from './array-base64-translator';\n\n// https://github.com/firebase/firebase-js-sdk/blob/7857c212f944a2a9eb421fd4cb7370181bc034b5/packages/messaging/src/interfaces/token-details.ts\nexport interface V2TokenDetails {\n fcmToken: string;\n swScope: string;\n vapidKey: string | Uint8Array;\n subscription: PushSubscription;\n fcmSenderId: string;\n fcmPushSet: string;\n createTime?: number;\n endpoint?: string;\n auth?: string;\n p256dh?: string;\n}\n\n// https://github.com/firebase/firebase-js-sdk/blob/6b5b15ce4ea3df5df5df8a8b33a4e41e249c7715/packages/messaging/src/interfaces/token-details.ts\nexport interface V3TokenDetails {\n fcmToken: string;\n swScope: string;\n vapidKey: Uint8Array;\n fcmSenderId: string;\n fcmPushSet: string;\n endpoint: string;\n auth: ArrayBuffer;\n p256dh: ArrayBuffer;\n createTime: number;\n}\n\n// https://github.com/firebase/firebase-js-sdk/blob/9567dba664732f681fa7fe60f5b7032bb1daf4c9/packages/messaging/src/interfaces/token-details.ts\nexport interface V4TokenDetails {\n fcmToken: string;\n swScope: string;\n vapidKey: Uint8Array;\n fcmSenderId: string;\n endpoint: string;\n auth: ArrayBufferLike;\n p256dh: ArrayBufferLike;\n createTime: number;\n}\n\nconst OLD_DB_NAME = 'fcm_token_details_db';\n/**\n * The last DB version of 'fcm_token_details_db' was 4. This is one higher, so that the upgrade\n * callback is called for all versions of the old DB.\n */\nconst OLD_DB_VERSION = 5;\nconst OLD_OBJECT_STORE_NAME = 'fcm_token_object_Store';\n\nexport async function migrateOldDatabase(\n senderId: string\n): Promise {\n if ('databases' in indexedDB) {\n // indexedDb.databases() is an IndexedDB v3 API and does not exist in all browsers. TODO: Remove\n // typecast when it lands in TS types.\n const databases = await (\n indexedDB as {\n databases(): Promise>;\n }\n ).databases();\n const dbNames = databases.map(db => db.name);\n\n if (!dbNames.includes(OLD_DB_NAME)) {\n // old DB didn't exist, no need to open.\n return null;\n }\n }\n\n let tokenDetails: TokenDetails | null = null;\n\n const db = await openDB(OLD_DB_NAME, OLD_DB_VERSION, {\n upgrade: async (db, oldVersion, newVersion, upgradeTransaction) => {\n if (oldVersion < 2) {\n // Database too old, skip migration.\n return;\n }\n\n if (!db.objectStoreNames.contains(OLD_OBJECT_STORE_NAME)) {\n // Database did not exist. Nothing to do.\n return;\n }\n\n const objectStore = upgradeTransaction.objectStore(OLD_OBJECT_STORE_NAME);\n const value = await objectStore.index('fcmSenderId').get(senderId);\n await objectStore.clear();\n\n if (!value) {\n // No entry in the database, nothing to migrate.\n return;\n }\n\n if (oldVersion === 2) {\n const oldDetails = value as V2TokenDetails;\n\n if (!oldDetails.auth || !oldDetails.p256dh || !oldDetails.endpoint) {\n return;\n }\n\n tokenDetails = {\n token: oldDetails.fcmToken,\n createTime: oldDetails.createTime ?? Date.now(),\n subscriptionOptions: {\n auth: oldDetails.auth,\n p256dh: oldDetails.p256dh,\n endpoint: oldDetails.endpoint,\n swScope: oldDetails.swScope,\n vapidKey:\n typeof oldDetails.vapidKey === 'string'\n ? oldDetails.vapidKey\n : arrayToBase64(oldDetails.vapidKey)\n }\n };\n } else if (oldVersion === 3) {\n const oldDetails = value as V3TokenDetails;\n\n tokenDetails = {\n token: oldDetails.fcmToken,\n createTime: oldDetails.createTime,\n subscriptionOptions: {\n auth: arrayToBase64(oldDetails.auth),\n p256dh: arrayToBase64(oldDetails.p256dh),\n endpoint: oldDetails.endpoint,\n swScope: oldDetails.swScope,\n vapidKey: arrayToBase64(oldDetails.vapidKey)\n }\n };\n } else if (oldVersion === 4) {\n const oldDetails = value as V4TokenDetails;\n\n tokenDetails = {\n token: oldDetails.fcmToken,\n createTime: oldDetails.createTime,\n subscriptionOptions: {\n auth: arrayToBase64(oldDetails.auth),\n p256dh: arrayToBase64(oldDetails.p256dh),\n endpoint: oldDetails.endpoint,\n swScope: oldDetails.swScope,\n vapidKey: arrayToBase64(oldDetails.vapidKey)\n }\n };\n }\n }\n });\n db.close();\n\n // Delete all old databases.\n await deleteDB(OLD_DB_NAME);\n await deleteDB('fcm_vapid_details_db');\n await deleteDB('undefined');\n\n return checkTokenDetails(tokenDetails) ? tokenDetails : null;\n}\n\nfunction checkTokenDetails(\n tokenDetails: TokenDetails | null\n): tokenDetails is TokenDetails {\n if (!tokenDetails || !tokenDetails.subscriptionOptions) {\n return false;\n }\n const { subscriptionOptions } = tokenDetails;\n return (\n typeof tokenDetails.createTime === 'number' &&\n tokenDetails.createTime > 0 &&\n typeof tokenDetails.token === 'string' &&\n tokenDetails.token.length > 0 &&\n typeof subscriptionOptions.auth === 'string' &&\n subscriptionOptions.auth.length > 0 &&\n typeof subscriptionOptions.p256dh === 'string' &&\n subscriptionOptions.p256dh.length > 0 &&\n typeof subscriptionOptions.endpoint === 'string' &&\n subscriptionOptions.endpoint.length > 0 &&\n typeof subscriptionOptions.swScope === 'string' &&\n subscriptionOptions.swScope.length > 0 &&\n typeof subscriptionOptions.vapidKey === 'string' &&\n subscriptionOptions.vapidKey.length > 0\n );\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { DBSchema, IDBPDatabase, deleteDB, openDB } from 'idb';\n\nimport { FirebaseInternalDependencies } from '../interfaces/internal-dependencies';\nimport { TokenDetails } from '../interfaces/token-details';\nimport { migrateOldDatabase } from '../helpers/migrate-old-database';\n\n// Exported for tests.\nexport const DATABASE_NAME = 'firebase-messaging-database';\nconst DATABASE_VERSION = 1;\nconst OBJECT_STORE_NAME = 'firebase-messaging-store';\n\ninterface MessagingDB extends DBSchema {\n 'firebase-messaging-store': {\n key: string;\n value: TokenDetails;\n };\n}\n\nlet dbPromise: Promise> | null = null;\nfunction getDbPromise(): Promise> {\n if (!dbPromise) {\n dbPromise = openDB(DATABASE_NAME, DATABASE_VERSION, {\n upgrade: (upgradeDb, oldVersion) => {\n // We don't use 'break' in this switch statement, the fall-through behavior is what we want,\n // because if there are multiple versions between the old version and the current version, we\n // want ALL the migrations that correspond to those versions to run, not only the last one.\n // eslint-disable-next-line default-case\n switch (oldVersion) {\n case 0:\n upgradeDb.createObjectStore(OBJECT_STORE_NAME);\n }\n }\n });\n }\n return dbPromise;\n}\n\n/** Gets record(s) from the objectStore that match the given key. */\nexport async function dbGet(\n firebaseDependencies: FirebaseInternalDependencies\n): Promise {\n const key = getKey(firebaseDependencies);\n const db = await getDbPromise();\n const tokenDetails = (await db\n .transaction(OBJECT_STORE_NAME)\n .objectStore(OBJECT_STORE_NAME)\n .get(key)) as TokenDetails;\n\n if (tokenDetails) {\n return tokenDetails;\n } else {\n // Check if there is a tokenDetails object in the old DB.\n const oldTokenDetails = await migrateOldDatabase(\n firebaseDependencies.appConfig.senderId\n );\n if (oldTokenDetails) {\n await dbSet(firebaseDependencies, oldTokenDetails);\n return oldTokenDetails;\n }\n }\n}\n\n/** Assigns or overwrites the record for the given key with the given value. */\nexport async function dbSet(\n firebaseDependencies: FirebaseInternalDependencies,\n tokenDetails: TokenDetails\n): Promise {\n const key = getKey(firebaseDependencies);\n const db = await getDbPromise();\n const tx = db.transaction(OBJECT_STORE_NAME, 'readwrite');\n await tx.objectStore(OBJECT_STORE_NAME).put(tokenDetails, key);\n await tx.done;\n return tokenDetails;\n}\n\n/** Removes record(s) from the objectStore that match the given key. */\nexport async function dbRemove(\n firebaseDependencies: FirebaseInternalDependencies\n): Promise {\n const key = getKey(firebaseDependencies);\n const db = await getDbPromise();\n const tx = db.transaction(OBJECT_STORE_NAME, 'readwrite');\n await tx.objectStore(OBJECT_STORE_NAME).delete(key);\n await tx.done;\n}\n\n/** Deletes the DB. Useful for tests. */\nexport async function dbDelete(): Promise {\n if (dbPromise) {\n (await dbPromise).close();\n await deleteDB(DATABASE_NAME);\n dbPromise = null;\n }\n}\n\nfunction getKey({ appConfig }: FirebaseInternalDependencies): string {\n return appConfig.appId;\n}\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ErrorFactory, ErrorMap } from '@firebase/util';\n\nexport const enum ErrorCode {\n MISSING_APP_CONFIG_VALUES = 'missing-app-config-values',\n AVAILABLE_IN_WINDOW = 'only-available-in-window',\n AVAILABLE_IN_SW = 'only-available-in-sw',\n PERMISSION_DEFAULT = 'permission-default',\n PERMISSION_BLOCKED = 'permission-blocked',\n UNSUPPORTED_BROWSER = 'unsupported-browser',\n INDEXED_DB_UNSUPPORTED = 'indexed-db-unsupported',\n FAILED_DEFAULT_REGISTRATION = 'failed-service-worker-registration',\n TOKEN_SUBSCRIBE_FAILED = 'token-subscribe-failed',\n TOKEN_SUBSCRIBE_NO_TOKEN = 'token-subscribe-no-token',\n TOKEN_UNSUBSCRIBE_FAILED = 'token-unsubscribe-failed',\n TOKEN_UPDATE_FAILED = 'token-update-failed',\n TOKEN_UPDATE_NO_TOKEN = 'token-update-no-token',\n INVALID_BG_HANDLER = 'invalid-bg-handler',\n USE_SW_AFTER_GET_TOKEN = 'use-sw-after-get-token',\n INVALID_SW_REGISTRATION = 'invalid-sw-registration',\n USE_VAPID_KEY_AFTER_GET_TOKEN = 'use-vapid-key-after-get-token',\n INVALID_VAPID_KEY = 'invalid-vapid-key'\n}\n\nexport const ERROR_MAP: ErrorMap = {\n [ErrorCode.MISSING_APP_CONFIG_VALUES]:\n 'Missing App configuration value: \"{$valueName}\"',\n [ErrorCode.AVAILABLE_IN_WINDOW]:\n 'This method is available in a Window context.',\n [ErrorCode.AVAILABLE_IN_SW]:\n 'This method is available in a service worker context.',\n [ErrorCode.PERMISSION_DEFAULT]:\n 'The notification permission was not granted and dismissed instead.',\n [ErrorCode.PERMISSION_BLOCKED]:\n 'The notification permission was not granted and blocked instead.',\n [ErrorCode.UNSUPPORTED_BROWSER]:\n \"This browser doesn't support the API's required to use the Firebase SDK.\",\n [ErrorCode.INDEXED_DB_UNSUPPORTED]:\n \"This browser doesn't support indexedDb.open() (ex. Safari iFrame, Firefox Private Browsing, etc)\",\n [ErrorCode.FAILED_DEFAULT_REGISTRATION]:\n 'We are unable to register the default service worker. {$browserErrorMessage}',\n [ErrorCode.TOKEN_SUBSCRIBE_FAILED]:\n 'A problem occurred while subscribing the user to FCM: {$errorInfo}',\n [ErrorCode.TOKEN_SUBSCRIBE_NO_TOKEN]:\n 'FCM returned no token when subscribing the user to push.',\n [ErrorCode.TOKEN_UNSUBSCRIBE_FAILED]:\n 'A problem occurred while unsubscribing the ' +\n 'user from FCM: {$errorInfo}',\n [ErrorCode.TOKEN_UPDATE_FAILED]:\n 'A problem occurred while updating the user from FCM: {$errorInfo}',\n [ErrorCode.TOKEN_UPDATE_NO_TOKEN]:\n 'FCM returned no token when updating the user to push.',\n [ErrorCode.USE_SW_AFTER_GET_TOKEN]:\n 'The useServiceWorker() method may only be called once and must be ' +\n 'called before calling getToken() to ensure your service worker is used.',\n [ErrorCode.INVALID_SW_REGISTRATION]:\n 'The input to useServiceWorker() must be a ServiceWorkerRegistration.',\n [ErrorCode.INVALID_BG_HANDLER]:\n 'The input to setBackgroundMessageHandler() must be a function.',\n [ErrorCode.INVALID_VAPID_KEY]: 'The public VAPID key must be a string.',\n [ErrorCode.USE_VAPID_KEY_AFTER_GET_TOKEN]:\n 'The usePublicVapidKey() method may only be called once and must be ' +\n 'called before calling getToken() to ensure your VAPID key is used.'\n};\n\ninterface ErrorParams {\n [ErrorCode.MISSING_APP_CONFIG_VALUES]: {\n valueName: string;\n };\n [ErrorCode.FAILED_DEFAULT_REGISTRATION]: { browserErrorMessage: string };\n [ErrorCode.TOKEN_SUBSCRIBE_FAILED]: { errorInfo: string };\n [ErrorCode.TOKEN_UNSUBSCRIBE_FAILED]: { errorInfo: string };\n [ErrorCode.TOKEN_UPDATE_FAILED]: { errorInfo: string };\n}\n\nexport const ERROR_FACTORY = new ErrorFactory(\n 'messaging',\n 'Messaging',\n ERROR_MAP\n);\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { DEFAULT_VAPID_KEY, ENDPOINT } from '../util/constants';\nimport { ERROR_FACTORY, ErrorCode } from '../util/errors';\nimport { SubscriptionOptions, TokenDetails } from '../interfaces/token-details';\n\nimport { AppConfig } from '../interfaces/app-config';\nimport { FirebaseInternalDependencies } from '../interfaces/internal-dependencies';\n\nexport interface ApiResponse {\n token?: string;\n error?: { message: string };\n}\n\nexport interface ApiRequestBody {\n web: {\n endpoint: string;\n p256dh: string;\n auth: string;\n applicationPubKey?: string;\n };\n}\n\nexport async function requestGetToken(\n firebaseDependencies: FirebaseInternalDependencies,\n subscriptionOptions: SubscriptionOptions\n): Promise {\n const headers = await getHeaders(firebaseDependencies);\n const body = getBody(subscriptionOptions);\n\n const subscribeOptions = {\n method: 'POST',\n headers,\n body: JSON.stringify(body)\n };\n\n let responseData: ApiResponse;\n try {\n const response = await fetch(\n getEndpoint(firebaseDependencies.appConfig),\n subscribeOptions\n );\n responseData = await response.json();\n } catch (err) {\n throw ERROR_FACTORY.create(ErrorCode.TOKEN_SUBSCRIBE_FAILED, {\n errorInfo: (err as Error)?.toString()\n });\n }\n\n if (responseData.error) {\n const message = responseData.error.message;\n throw ERROR_FACTORY.create(ErrorCode.TOKEN_SUBSCRIBE_FAILED, {\n errorInfo: message\n });\n }\n\n if (!responseData.token) {\n throw ERROR_FACTORY.create(ErrorCode.TOKEN_SUBSCRIBE_NO_TOKEN);\n }\n\n return responseData.token;\n}\n\nexport async function requestUpdateToken(\n firebaseDependencies: FirebaseInternalDependencies,\n tokenDetails: TokenDetails\n): Promise {\n const headers = await getHeaders(firebaseDependencies);\n const body = getBody(tokenDetails.subscriptionOptions!);\n\n const updateOptions = {\n method: 'PATCH',\n headers,\n body: JSON.stringify(body)\n };\n\n let responseData: ApiResponse;\n try {\n const response = await fetch(\n `${getEndpoint(firebaseDependencies.appConfig)}/${tokenDetails.token}`,\n updateOptions\n );\n responseData = await response.json();\n } catch (err) {\n throw ERROR_FACTORY.create(ErrorCode.TOKEN_UPDATE_FAILED, {\n errorInfo: (err as Error)?.toString()\n });\n }\n\n if (responseData.error) {\n const message = responseData.error.message;\n throw ERROR_FACTORY.create(ErrorCode.TOKEN_UPDATE_FAILED, {\n errorInfo: message\n });\n }\n\n if (!responseData.token) {\n throw ERROR_FACTORY.create(ErrorCode.TOKEN_UPDATE_NO_TOKEN);\n }\n\n return responseData.token;\n}\n\nexport async function requestDeleteToken(\n firebaseDependencies: FirebaseInternalDependencies,\n token: string\n): Promise {\n const headers = await getHeaders(firebaseDependencies);\n\n const unsubscribeOptions = {\n method: 'DELETE',\n headers\n };\n\n try {\n const response = await fetch(\n `${getEndpoint(firebaseDependencies.appConfig)}/${token}`,\n unsubscribeOptions\n );\n const responseData: ApiResponse = await response.json();\n if (responseData.error) {\n const message = responseData.error.message;\n throw ERROR_FACTORY.create(ErrorCode.TOKEN_UNSUBSCRIBE_FAILED, {\n errorInfo: message\n });\n }\n } catch (err) {\n throw ERROR_FACTORY.create(ErrorCode.TOKEN_UNSUBSCRIBE_FAILED, {\n errorInfo: (err as Error)?.toString()\n });\n }\n}\n\nfunction getEndpoint({ projectId }: AppConfig): string {\n return `${ENDPOINT}/projects/${projectId!}/registrations`;\n}\n\nasync function getHeaders({\n appConfig,\n installations\n}: FirebaseInternalDependencies): Promise {\n const authToken = await installations.getToken();\n\n return new Headers({\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n 'x-goog-api-key': appConfig.apiKey!,\n 'x-goog-firebase-installations-auth': `FIS ${authToken}`\n });\n}\n\nfunction getBody({\n p256dh,\n auth,\n endpoint,\n vapidKey\n}: SubscriptionOptions): ApiRequestBody {\n const body: ApiRequestBody = {\n web: {\n endpoint,\n auth,\n p256dh\n }\n };\n\n if (vapidKey !== DEFAULT_VAPID_KEY) {\n body.web.applicationPubKey = vapidKey;\n }\n\n return body;\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { SubscriptionOptions, TokenDetails } from '../interfaces/token-details';\nimport {\n arrayToBase64,\n base64ToArray\n} from '../helpers/array-base64-translator';\nimport { dbGet, dbRemove, dbSet } from './idb-manager';\nimport {\n requestDeleteToken,\n requestGetToken,\n requestUpdateToken\n} from './requests';\n\nimport { FirebaseInternalDependencies } from '../interfaces/internal-dependencies';\nimport { MessagingService } from '../messaging-service';\n\n// UpdateRegistration will be called once every week.\nconst TOKEN_EXPIRATION_MS = 7 * 24 * 60 * 60 * 1000; // 7 days\n\nexport async function getTokenInternal(\n messaging: MessagingService\n): Promise {\n const pushSubscription = await getPushSubscription(\n messaging.swRegistration!,\n messaging.vapidKey!\n );\n\n const subscriptionOptions: SubscriptionOptions = {\n vapidKey: messaging.vapidKey!,\n swScope: messaging.swRegistration!.scope,\n endpoint: pushSubscription.endpoint,\n auth: arrayToBase64(pushSubscription.getKey('auth')!),\n p256dh: arrayToBase64(pushSubscription.getKey('p256dh')!)\n };\n\n const tokenDetails = await dbGet(messaging.firebaseDependencies);\n if (!tokenDetails) {\n // No token, get a new one.\n return getNewToken(messaging.firebaseDependencies, subscriptionOptions);\n } else if (\n !isTokenValid(tokenDetails.subscriptionOptions!, subscriptionOptions)\n ) {\n // Invalid token, get a new one.\n try {\n await requestDeleteToken(\n messaging.firebaseDependencies!,\n tokenDetails.token\n );\n } catch (e) {\n // Suppress errors because of #2364\n console.warn(e);\n }\n\n return getNewToken(messaging.firebaseDependencies!, subscriptionOptions);\n } else if (Date.now() >= tokenDetails.createTime + TOKEN_EXPIRATION_MS) {\n // Weekly token refresh\n return updateToken(messaging, {\n token: tokenDetails.token,\n createTime: Date.now(),\n subscriptionOptions\n });\n } else {\n // Valid token, nothing to do.\n return tokenDetails.token;\n }\n}\n\n/**\n * This method deletes the token from the database, unsubscribes the token from FCM, and unregisters\n * the push subscription if it exists.\n */\nexport async function deleteTokenInternal(\n messaging: MessagingService\n): Promise {\n const tokenDetails = await dbGet(messaging.firebaseDependencies);\n if (tokenDetails) {\n await requestDeleteToken(\n messaging.firebaseDependencies,\n tokenDetails.token\n );\n await dbRemove(messaging.firebaseDependencies);\n }\n\n // Unsubscribe from the push subscription.\n const pushSubscription =\n await messaging.swRegistration!.pushManager.getSubscription();\n if (pushSubscription) {\n return pushSubscription.unsubscribe();\n }\n\n // If there's no SW, consider it a success.\n return true;\n}\n\nasync function updateToken(\n messaging: MessagingService,\n tokenDetails: TokenDetails\n): Promise {\n try {\n const updatedToken = await requestUpdateToken(\n messaging.firebaseDependencies,\n tokenDetails\n );\n\n const updatedTokenDetails: TokenDetails = {\n ...tokenDetails,\n token: updatedToken,\n createTime: Date.now()\n };\n\n await dbSet(messaging.firebaseDependencies, updatedTokenDetails);\n return updatedToken;\n } catch (e) {\n await deleteTokenInternal(messaging);\n throw e;\n }\n}\n\nasync function getNewToken(\n firebaseDependencies: FirebaseInternalDependencies,\n subscriptionOptions: SubscriptionOptions\n): Promise {\n const token = await requestGetToken(\n firebaseDependencies,\n subscriptionOptions\n );\n const tokenDetails: TokenDetails = {\n token,\n createTime: Date.now(),\n subscriptionOptions\n };\n await dbSet(firebaseDependencies, tokenDetails);\n return tokenDetails.token;\n}\n\n/**\n * Gets a PushSubscription for the current user.\n */\nasync function getPushSubscription(\n swRegistration: ServiceWorkerRegistration,\n vapidKey: string\n): Promise {\n const subscription = await swRegistration.pushManager.getSubscription();\n if (subscription) {\n return subscription;\n }\n\n return swRegistration.pushManager.subscribe({\n userVisibleOnly: true,\n // Chrome <= 75 doesn't support base64-encoded VAPID key. For backward compatibility, VAPID key\n // submitted to pushManager#subscribe must be of type Uint8Array.\n applicationServerKey: base64ToArray(vapidKey)\n });\n}\n\n/**\n * Checks if the saved tokenDetails object matches the configuration provided.\n */\nfunction isTokenValid(\n dbOptions: SubscriptionOptions,\n currentOptions: SubscriptionOptions\n): boolean {\n const isVapidKeyEqual = currentOptions.vapidKey === dbOptions.vapidKey;\n const isEndpointEqual = currentOptions.endpoint === dbOptions.endpoint;\n const isAuthEqual = currentOptions.auth === dbOptions.auth;\n const isP256dhEqual = currentOptions.p256dh === dbOptions.p256dh;\n\n return isVapidKeyEqual && isEndpointEqual && isAuthEqual && isP256dhEqual;\n}\n", "/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { MessagePayload } from '../interfaces/public-types';\nimport { MessagePayloadInternal } from '../interfaces/internal-message-payload';\n\nexport function externalizePayload(\n internalPayload: MessagePayloadInternal\n): MessagePayload {\n const payload: MessagePayload = {\n from: internalPayload.from,\n // eslint-disable-next-line camelcase\n collapseKey: internalPayload.collapse_key,\n // eslint-disable-next-line camelcase\n messageId: internalPayload.fcmMessageId\n } as MessagePayload;\n\n propagateNotificationPayload(payload, internalPayload);\n propagateDataPayload(payload, internalPayload);\n propagateFcmOptions(payload, internalPayload);\n\n return payload;\n}\n\nfunction propagateNotificationPayload(\n payload: MessagePayload,\n messagePayloadInternal: MessagePayloadInternal\n): void {\n if (!messagePayloadInternal.notification) {\n return;\n }\n\n payload.notification = {};\n\n const title = messagePayloadInternal.notification!.title;\n if (!!title) {\n payload.notification!.title = title;\n }\n\n const body = messagePayloadInternal.notification!.body;\n if (!!body) {\n payload.notification!.body = body;\n }\n\n const image = messagePayloadInternal.notification!.image;\n if (!!image) {\n payload.notification!.image = image;\n }\n}\n\nfunction propagateDataPayload(\n payload: MessagePayload,\n messagePayloadInternal: MessagePayloadInternal\n): void {\n if (!messagePayloadInternal.data) {\n return;\n }\n\n payload.data = messagePayloadInternal.data as { [key: string]: string };\n}\n\nfunction propagateFcmOptions(\n payload: MessagePayload,\n messagePayloadInternal: MessagePayloadInternal\n): void {\n // fcmOptions.link value is written into notification.click_action. see more in b/232072111\n if (\n !messagePayloadInternal.fcmOptions &&\n !messagePayloadInternal.notification?.click_action\n ) {\n return;\n }\n\n payload.fcmOptions = {};\n\n const link =\n messagePayloadInternal.fcmOptions?.link ??\n messagePayloadInternal.notification?.click_action;\n\n if (!!link) {\n payload.fcmOptions!.link = link;\n }\n\n // eslint-disable-next-line camelcase\n const analyticsLabel = messagePayloadInternal.fcmOptions?.analytics_label;\n if (!!analyticsLabel) {\n payload.fcmOptions!.analyticsLabel = analyticsLabel;\n }\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { CONSOLE_CAMPAIGN_ID } from '../util/constants';\nimport { ConsoleMessageData } from '../interfaces/internal-message-payload';\n\nexport function isConsoleMessage(data: unknown): data is ConsoleMessageData {\n // This message has a campaign ID, meaning it was sent using the Firebase Console.\n return typeof data === 'object' && !!data && CONSOLE_CAMPAIGN_ID in data;\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/** Returns a promise that resolves after given time passes. */\nexport function sleep(ms: number): Promise {\n return new Promise(resolve => {\n setTimeout(resolve, ms);\n });\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n DEFAULT_BACKOFF_TIME_MS,\n EVENT_MESSAGE_DELIVERED,\n FCM_LOG_SOURCE,\n LOG_INTERVAL_IN_MS,\n MAX_NUMBER_OF_EVENTS_PER_LOG_REQUEST,\n MAX_RETRIES,\n MessageType,\n SDK_PLATFORM_WEB\n} from '../util/constants';\nimport {\n FcmEvent,\n LogEvent,\n LogRequest,\n LogResponse\n} from '../interfaces/logging-types';\n\nimport { MessagePayloadInternal } from '../interfaces/internal-message-payload';\nimport { MessagingService } from '../messaging-service';\n\nconst FIRELOG_ENDPOINT = _mergeStrings(\n 'hts/frbslgigp.ogepscmv/ieo/eaylg',\n 'tp:/ieaeogn-agolai.o/1frlglgc/o'\n);\n\nconst FCM_TRANSPORT_KEY = _mergeStrings(\n 'AzSCbw63g1R0nCw85jG8',\n 'Iaya3yLKwmgvh7cF0q4'\n);\n\nexport function startLoggingService(messaging: MessagingService): void {\n if (!messaging.isLogServiceStarted) {\n _processQueue(messaging, LOG_INTERVAL_IN_MS);\n messaging.isLogServiceStarted = true;\n }\n}\n\n/**\n *\n * @param messaging the messaging instance.\n * @param offsetInMs this method execute after `offsetInMs` elapsed .\n */\nexport function _processQueue(\n messaging: MessagingService,\n offsetInMs: number\n): void {\n setTimeout(async () => {\n if (!messaging.deliveryMetricsExportedToBigQueryEnabled) {\n // flush events and terminate logging service\n messaging.logEvents = [];\n messaging.isLogServiceStarted = false;\n\n return;\n }\n\n if (!messaging.logEvents.length) {\n return _processQueue(messaging, LOG_INTERVAL_IN_MS);\n }\n\n await _dispatchLogEvents(messaging);\n }, offsetInMs);\n}\n\nexport async function _dispatchLogEvents(\n messaging: MessagingService\n): Promise {\n for (\n let i = 0, n = messaging.logEvents.length;\n i < n;\n i += MAX_NUMBER_OF_EVENTS_PER_LOG_REQUEST\n ) {\n const logRequest = _createLogRequest(\n messaging.logEvents.slice(i, i + MAX_NUMBER_OF_EVENTS_PER_LOG_REQUEST)\n );\n\n let retryCount = 0,\n response = {} as Response;\n\n do {\n try {\n response = await fetch(\n FIRELOG_ENDPOINT.concat('?key=', FCM_TRANSPORT_KEY),\n {\n method: 'POST',\n body: JSON.stringify(logRequest)\n }\n );\n\n // don't retry on 200s or non retriable errors\n if (response.ok || (!response.ok && !isRetriableError(response))) {\n break;\n }\n\n if (!response.ok && isRetriableError(response)) {\n // rethrow to retry with quota\n throw new Error(\n 'a retriable Non-200 code is returned in fetch to Firelog endpoint. Retry'\n );\n }\n } catch (error) {\n const isLastAttempt = retryCount === MAX_RETRIES;\n if (isLastAttempt) {\n // existing the do-while interactive retry logic because retry quota has reached.\n break;\n }\n }\n\n let delayInMs: number;\n try {\n delayInMs = Number(\n ((await response.json()) as LogResponse).nextRequestWaitMillis\n );\n } catch (e) {\n delayInMs = DEFAULT_BACKOFF_TIME_MS;\n }\n\n await new Promise(resolve => setTimeout(resolve, delayInMs));\n\n retryCount++;\n } while (retryCount < MAX_RETRIES);\n }\n\n messaging.logEvents = [];\n // schedule for next logging\n _processQueue(messaging, LOG_INTERVAL_IN_MS);\n}\n\nfunction isRetriableError(response: Response): boolean {\n const httpStatus = response.status;\n\n return (\n httpStatus === 429 ||\n httpStatus === 500 ||\n httpStatus === 503 ||\n httpStatus === 504\n );\n}\n\nexport async function stageLog(\n messaging: MessagingService,\n internalPayload: MessagePayloadInternal\n): Promise {\n const fcmEvent = createFcmEvent(\n internalPayload,\n await messaging.firebaseDependencies.installations.getId()\n );\n\n createAndEnqueueLogEvent(messaging, fcmEvent);\n}\n\nfunction createFcmEvent(\n internalPayload: MessagePayloadInternal,\n fid: string\n): FcmEvent {\n const fcmEvent = {} as FcmEvent;\n\n /* eslint-disable camelcase */\n // some fields should always be non-null. Still check to ensure.\n if (!!internalPayload.from) {\n fcmEvent.project_number = internalPayload.from;\n }\n\n if (!!internalPayload.fcmMessageId) {\n fcmEvent.message_id = internalPayload.fcmMessageId;\n }\n\n fcmEvent.instance_id = fid;\n\n if (!!internalPayload.notification) {\n fcmEvent.message_type = MessageType.DISPLAY_NOTIFICATION.toString();\n } else {\n fcmEvent.message_type = MessageType.DATA_MESSAGE.toString();\n }\n\n fcmEvent.sdk_platform = SDK_PLATFORM_WEB.toString();\n fcmEvent.package_name = self.origin.replace(/(^\\w+:|^)\\/\\//, '');\n\n if (!!internalPayload.collapse_key) {\n fcmEvent.collapse_key = internalPayload.collapse_key;\n }\n\n fcmEvent.event = EVENT_MESSAGE_DELIVERED.toString();\n\n if (!!internalPayload.fcmOptions?.analytics_label) {\n fcmEvent.analytics_label = internalPayload.fcmOptions?.analytics_label;\n }\n\n /* eslint-enable camelcase */\n return fcmEvent;\n}\n\nfunction createAndEnqueueLogEvent(\n messaging: MessagingService,\n fcmEvent: FcmEvent\n): void {\n const logEvent = {} as LogEvent;\n\n /* eslint-disable camelcase */\n logEvent.event_time_ms = Math.floor(Date.now()).toString();\n logEvent.source_extension_json_proto3 = JSON.stringify(fcmEvent);\n // eslint-disable-next-line camelcase\n\n messaging.logEvents.push(logEvent);\n}\n\nexport function _createLogRequest(logEventQueue: LogEvent[]): LogRequest {\n const logRequest = {} as LogRequest;\n\n /* eslint-disable camelcase */\n logRequest.log_source = FCM_LOG_SOURCE.toString();\n logRequest.log_event = logEventQueue;\n /* eslint-enable camelcase */\n\n return logRequest;\n}\n\nexport function _mergeStrings(s1: string, s2: string): string {\n const resultArray = [];\n for (let i = 0; i < s1.length; i++) {\n resultArray.push(s1.charAt(i));\n if (i < s2.length) {\n resultArray.push(s2.charAt(i));\n }\n }\n\n return resultArray.join('');\n}\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { DEFAULT_VAPID_KEY, FCM_MSG } from '../util/constants';\nimport {\n MessagePayloadInternal,\n MessageType,\n NotificationPayloadInternal\n} from '../interfaces/internal-message-payload';\nimport {\n NotificationEvent,\n PushEvent,\n PushSubscriptionChangeEvent,\n ServiceWorkerGlobalScope,\n WindowClient\n} from '../util/sw-types';\nimport {\n deleteTokenInternal,\n getTokenInternal\n} from '../internals/token-manager';\n\nimport { MessagingService } from '../messaging-service';\nimport { dbGet } from '../internals/idb-manager';\nimport { externalizePayload } from '../helpers/externalizePayload';\nimport { isConsoleMessage } from '../helpers/is-console-message';\nimport { sleep } from '../helpers/sleep';\nimport { stageLog } from '../helpers/logToFirelog';\n\n// Let TS know that this is a service worker\ndeclare const self: ServiceWorkerGlobalScope;\n\nexport async function onSubChange(\n event: PushSubscriptionChangeEvent,\n messaging: MessagingService\n): Promise {\n const { newSubscription } = event;\n if (!newSubscription) {\n // Subscription revoked, delete token\n await deleteTokenInternal(messaging);\n return;\n }\n\n const tokenDetails = await dbGet(messaging.firebaseDependencies);\n await deleteTokenInternal(messaging);\n\n messaging.vapidKey =\n tokenDetails?.subscriptionOptions?.vapidKey ?? DEFAULT_VAPID_KEY;\n await getTokenInternal(messaging);\n}\n\nexport async function onPush(\n event: PushEvent,\n messaging: MessagingService\n): Promise {\n const internalPayload = getMessagePayloadInternal(event);\n if (!internalPayload) {\n // Failed to get parsed MessagePayload from the PushEvent. Skip handling the push.\n return;\n }\n\n // log to Firelog with user consent\n if (messaging.deliveryMetricsExportedToBigQueryEnabled) {\n await stageLog(messaging, internalPayload);\n }\n\n // foreground handling: eventually passed to onMessage hook\n const clientList = await getClientList();\n if (hasVisibleClients(clientList)) {\n return sendMessagePayloadInternalToWindows(clientList, internalPayload);\n }\n\n // background handling: display if possible and pass to onBackgroundMessage hook\n if (!!internalPayload.notification) {\n await showNotification(wrapInternalPayload(internalPayload));\n }\n\n if (!messaging) {\n return;\n }\n\n if (!!messaging.onBackgroundMessageHandler) {\n const payload = externalizePayload(internalPayload);\n\n if (typeof messaging.onBackgroundMessageHandler === 'function') {\n await messaging.onBackgroundMessageHandler(payload);\n } else {\n messaging.onBackgroundMessageHandler.next(payload);\n }\n }\n}\n\nexport async function onNotificationClick(\n event: NotificationEvent\n): Promise {\n const internalPayload: MessagePayloadInternal =\n event.notification?.data?.[FCM_MSG];\n\n if (!internalPayload) {\n return;\n } else if (event.action) {\n // User clicked on an action button. This will allow developers to act on action button clicks\n // by using a custom onNotificationClick listener that they define.\n return;\n }\n\n // Prevent other listeners from receiving the event\n event.stopImmediatePropagation();\n event.notification.close();\n\n // Note clicking on a notification with no link set will focus the Chrome's current tab.\n const link = getLink(internalPayload);\n if (!link) {\n return;\n }\n\n // FM should only open/focus links from app's origin.\n const url = new URL(link, self.location.href);\n const originUrl = new URL(self.location.origin);\n\n if (url.host !== originUrl.host) {\n return;\n }\n\n let client = await getWindowClient(url);\n\n if (!client) {\n client = await self.clients.openWindow(link);\n\n // Wait three seconds for the client to initialize and set up the message handler so that it\n // can receive the message.\n await sleep(3000);\n } else {\n client = await client.focus();\n }\n\n if (!client) {\n // Window Client will not be returned if it's for a third party origin.\n return;\n }\n\n internalPayload.messageType = MessageType.NOTIFICATION_CLICKED;\n internalPayload.isFirebaseMessaging = true;\n return client.postMessage(internalPayload);\n}\n\nfunction wrapInternalPayload(\n internalPayload: MessagePayloadInternal\n): NotificationPayloadInternal {\n const wrappedInternalPayload: NotificationPayloadInternal = {\n ...(internalPayload.notification as unknown as NotificationPayloadInternal)\n };\n\n // Put the message payload under FCM_MSG name so we can identify the notification as being an FCM\n // notification vs a notification from somewhere else (i.e. normal web push or developer generated\n // notification).\n wrappedInternalPayload.data = {\n [FCM_MSG]: internalPayload\n };\n\n return wrappedInternalPayload;\n}\n\nfunction getMessagePayloadInternal({\n data\n}: PushEvent): MessagePayloadInternal | null {\n if (!data) {\n return null;\n }\n\n try {\n return data.json();\n } catch (err) {\n // Not JSON so not an FCM message.\n return null;\n }\n}\n\n/**\n * @param url The URL to look for when focusing a client.\n * @return Returns an existing window client or a newly opened WindowClient.\n */\nasync function getWindowClient(url: URL): Promise {\n const clientList = await getClientList();\n\n for (const client of clientList) {\n const clientUrl = new URL(client.url, self.location.href);\n\n if (url.host === clientUrl.host) {\n return client;\n }\n }\n\n return null;\n}\n\n/**\n * @returns If there is currently a visible WindowClient, this method will resolve to true,\n * otherwise false.\n */\nfunction hasVisibleClients(clientList: WindowClient[]): boolean {\n return clientList.some(\n client =>\n client.visibilityState === 'visible' &&\n // Ignore chrome-extension clients as that matches the background pages of extensions, which\n // are always considered visible for some reason.\n !client.url.startsWith('chrome-extension://')\n );\n}\n\nfunction sendMessagePayloadInternalToWindows(\n clientList: WindowClient[],\n internalPayload: MessagePayloadInternal\n): void {\n internalPayload.isFirebaseMessaging = true;\n internalPayload.messageType = MessageType.PUSH_RECEIVED;\n\n for (const client of clientList) {\n client.postMessage(internalPayload);\n }\n}\n\nfunction getClientList(): Promise {\n return self.clients.matchAll({\n type: 'window',\n includeUncontrolled: true\n // TS doesn't know that \"type: 'window'\" means it'll return WindowClient[]\n }) as Promise;\n}\n\nfunction showNotification(\n notificationPayloadInternal: NotificationPayloadInternal\n): Promise {\n // Note: Firefox does not support the maxActions property.\n // https://developer.mozilla.org/en-US/docs/Web/API/notification/maxActions\n const { actions } = notificationPayloadInternal;\n const { maxActions } = Notification;\n if (actions && maxActions && actions.length > maxActions) {\n console.warn(\n `This browser only supports ${maxActions} actions. The remaining actions will not be displayed.`\n );\n }\n\n return self.registration.showNotification(\n /* title= */ notificationPayloadInternal.title ?? '',\n notificationPayloadInternal\n );\n}\n\nfunction getLink(payload: MessagePayloadInternal): string | null {\n // eslint-disable-next-line camelcase\n const link = payload.fcmOptions?.link ?? payload.notification?.click_action;\n if (link) {\n return link;\n }\n\n if (isConsoleMessage(payload.data)) {\n // Notification created in the Firebase Console. Redirect to origin.\n return self.location.origin;\n } else {\n return null;\n }\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ERROR_FACTORY, ErrorCode } from '../util/errors';\nimport { FirebaseApp, FirebaseOptions } from '@firebase/app';\n\nimport { AppConfig } from '../interfaces/app-config';\nimport { FirebaseError } from '@firebase/util';\n\nexport function extractAppConfig(app: FirebaseApp): AppConfig {\n if (!app || !app.options) {\n throw getMissingValueError('App Configuration Object');\n }\n\n if (!app.name) {\n throw getMissingValueError('App Name');\n }\n\n // Required app config keys\n const configKeys: ReadonlyArray = [\n 'projectId',\n 'apiKey',\n 'appId',\n 'messagingSenderId'\n ];\n\n const { options } = app;\n for (const keyName of configKeys) {\n if (!options[keyName]) {\n throw getMissingValueError(keyName);\n }\n }\n\n return {\n appName: app.name,\n projectId: options.projectId!,\n apiKey: options.apiKey!,\n appId: options.appId!,\n senderId: options.messagingSenderId!\n };\n}\n\nfunction getMissingValueError(valueName: string): FirebaseError {\n return ERROR_FACTORY.create(ErrorCode.MISSING_APP_CONFIG_VALUES, {\n valueName\n });\n}\n", "/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { FirebaseApp, _FirebaseService } from '@firebase/app';\nimport { MessagePayload, NextFn, Observer } from './interfaces/public-types';\n\nimport { FirebaseAnalyticsInternalName } from '@firebase/analytics-interop-types';\nimport { FirebaseInternalDependencies } from './interfaces/internal-dependencies';\nimport { LogEvent } from './interfaces/logging-types';\nimport { Provider } from '@firebase/component';\nimport { _FirebaseInstallationsInternal } from '@firebase/installations';\nimport { extractAppConfig } from './helpers/extract-app-config';\n\nexport class MessagingService implements _FirebaseService {\n readonly app!: FirebaseApp;\n readonly firebaseDependencies!: FirebaseInternalDependencies;\n\n swRegistration?: ServiceWorkerRegistration;\n vapidKey?: string;\n // logging is only done with end user consent. Default to false.\n deliveryMetricsExportedToBigQueryEnabled: boolean = false;\n\n onBackgroundMessageHandler:\n | NextFn\n | Observer\n | null = null;\n\n onMessageHandler: NextFn | Observer | null =\n null;\n\n logEvents: LogEvent[] = [];\n isLogServiceStarted: boolean = false;\n\n constructor(\n app: FirebaseApp,\n installations: _FirebaseInstallationsInternal,\n analyticsProvider: Provider\n ) {\n const appConfig = extractAppConfig(app);\n\n this.firebaseDependencies = {\n app,\n appConfig,\n installations,\n analyticsProvider\n };\n }\n\n _delete(): Promise {\n return Promise.resolve();\n }\n}\n", "/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n Component,\n ComponentContainer,\n ComponentType,\n InstanceFactory\n} from '@firebase/component';\nimport {\n onNotificationClick,\n onPush,\n onSubChange\n} from '../listeners/sw-listeners';\n\nimport { GetTokenOptions } from '../interfaces/public-types';\nimport { MessagingInternal } from '@firebase/messaging-interop-types';\nimport { MessagingService } from '../messaging-service';\nimport { ServiceWorkerGlobalScope } from '../util/sw-types';\nimport { _registerComponent, registerVersion } from '@firebase/app';\nimport { getToken } from '../api/getToken';\nimport { messageEventListener } from '../listeners/window-listener';\n\nimport { name, version } from '../../package.json';\n\nconst WindowMessagingFactory: InstanceFactory<'messaging'> = (\n container: ComponentContainer\n) => {\n const messaging = new MessagingService(\n container.getProvider('app').getImmediate(),\n container.getProvider('installations-internal').getImmediate(),\n container.getProvider('analytics-internal')\n );\n\n navigator.serviceWorker.addEventListener('message', e =>\n messageEventListener(messaging as MessagingService, e)\n );\n\n return messaging;\n};\n\nconst WindowMessagingInternalFactory: InstanceFactory<'messaging-internal'> = (\n container: ComponentContainer\n) => {\n const messaging = container\n .getProvider('messaging')\n .getImmediate() as MessagingService;\n\n const messagingInternal: MessagingInternal = {\n getToken: (options?: GetTokenOptions) => getToken(messaging, options)\n };\n\n return messagingInternal;\n};\n\ndeclare const self: ServiceWorkerGlobalScope;\nconst SwMessagingFactory: InstanceFactory<'messaging'> = (\n container: ComponentContainer\n) => {\n const messaging = new MessagingService(\n container.getProvider('app').getImmediate(),\n container.getProvider('installations-internal').getImmediate(),\n container.getProvider('analytics-internal')\n );\n\n self.addEventListener('push', e => {\n e.waitUntil(onPush(e, messaging as MessagingService));\n });\n self.addEventListener('pushsubscriptionchange', e => {\n e.waitUntil(onSubChange(e, messaging as MessagingService));\n });\n self.addEventListener('notificationclick', e => {\n e.waitUntil(onNotificationClick(e));\n });\n\n return messaging;\n};\n\nexport function registerMessagingInWindow(): void {\n _registerComponent(\n new Component('messaging', WindowMessagingFactory, ComponentType.PUBLIC)\n );\n\n _registerComponent(\n new Component(\n 'messaging-internal',\n WindowMessagingInternalFactory,\n ComponentType.PRIVATE\n )\n );\n\n registerVersion(name, version);\n // BUILD_TARGET will be replaced by values like esm5, esm2017, cjs5, etc during the compilation\n registerVersion(name, version, '__BUILD_TARGET__');\n}\n\n/**\n * The messaging instance registered in sw is named differently than that of in client. This is\n * because both `registerMessagingInWindow` and `registerMessagingInSw` would be called in\n * `messaging-compat` and component with the same name can only be registered once.\n */\nexport function registerMessagingInSw(): void {\n _registerComponent(\n new Component('messaging-sw', SwMessagingFactory, ComponentType.PUBLIC)\n );\n}\n", "/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n areCookiesEnabled,\n isIndexedDBAvailable,\n validateIndexedDBOpenable\n} from '@firebase/util';\n\n/**\n * Checks if all required APIs exist in the browser.\n * @returns a Promise that resolves to a boolean.\n *\n * @public\n */\nexport async function isWindowSupported(): Promise {\n try {\n // This throws if open() is unsupported, so adding it to the conditional\n // statement below can cause an uncaught error.\n await validateIndexedDBOpenable();\n } catch (e) {\n return false;\n }\n // firebase-js-sdk/issues/2393 reveals that idb#open in Safari iframe and Firefox private browsing\n // might be prohibited to run. In these contexts, an error would be thrown during the messaging\n // instantiating phase, informing the developers to import/call isSupported for special handling.\n return (\n typeof window !== 'undefined' &&\n isIndexedDBAvailable() &&\n areCookiesEnabled() &&\n 'serviceWorker' in navigator &&\n 'PushManager' in window &&\n 'Notification' in window &&\n 'fetch' in window &&\n ServiceWorkerRegistration.prototype.hasOwnProperty('showNotification') &&\n PushSubscription.prototype.hasOwnProperty('getKey')\n );\n}\n\n/**\n * Checks whether all required APIs exist within SW Context\n * @returns a Promise that resolves to a boolean.\n *\n * @public\n */\nexport async function isSwSupported(): Promise {\n // firebase-js-sdk/issues/2393 reveals that idb#open in Safari iframe and Firefox private browsing\n // might be prohibited to run. In these contexts, an error would be thrown during the messaging\n // instantiating phase, informing the developers to import/call isSupported for special handling.\n return (\n isIndexedDBAvailable() &&\n (await validateIndexedDBOpenable()) &&\n 'PushManager' in self &&\n 'Notification' in self &&\n ServiceWorkerRegistration.prototype.hasOwnProperty('showNotification') &&\n PushSubscription.prototype.hasOwnProperty('getKey')\n );\n}\n", "/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ERROR_FACTORY, ErrorCode } from '../util/errors';\n\nimport {\n MessagePayload,\n NextFn,\n Observer,\n Unsubscribe\n} from '../interfaces/public-types';\nimport { MessagingService } from '../messaging-service';\n\nexport function onBackgroundMessage(\n messaging: MessagingService,\n nextOrObserver: NextFn | Observer\n): Unsubscribe {\n if (self.document !== undefined) {\n throw ERROR_FACTORY.create(ErrorCode.AVAILABLE_IN_SW);\n }\n\n messaging.onBackgroundMessageHandler = nextOrObserver;\n\n return () => {\n messaging.onBackgroundMessageHandler = null;\n };\n}\n", "/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Messaging } from '../interfaces/public-types';\nimport { MessagingService } from '../messaging-service';\n\nexport function _setDeliveryMetricsExportedToBigQueryEnabled(\n messaging: Messaging,\n enable: boolean\n): void {\n (messaging as MessagingService).deliveryMetricsExportedToBigQueryEnabled =\n enable;\n}\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ERROR_FACTORY, ErrorCode } from './util/errors';\nimport { FirebaseApp, _getProvider, getApp } from '@firebase/app';\nimport {\n GetTokenOptions,\n MessagePayload,\n Messaging\n} from './interfaces/public-types';\nimport {\n NextFn,\n Observer,\n Unsubscribe,\n getModularInstance\n} from '@firebase/util';\nimport { isSwSupported, isWindowSupported } from './api/isSupported';\n\nimport { MessagingService } from './messaging-service';\nimport { deleteToken as _deleteToken } from './api/deleteToken';\nimport { getToken as _getToken } from './api/getToken';\nimport { onBackgroundMessage as _onBackgroundMessage } from './api/onBackgroundMessage';\nimport { onMessage as _onMessage } from './api/onMessage';\nimport { _setDeliveryMetricsExportedToBigQueryEnabled } from './api/setDeliveryMetricsExportedToBigQueryEnabled';\n\n/**\n * Retrieves a Firebase Cloud Messaging instance.\n *\n * @returns The Firebase Cloud Messaging instance associated with the provided firebase app.\n *\n * @public\n */\nexport function getMessagingInWindow(app: FirebaseApp = getApp()): Messaging {\n // Conscious decision to make this async check non-blocking during the messaging instance\n // initialization phase for performance consideration. An error would be thrown latter for\n // developer's information. Developers can then choose to import and call `isSupported` for\n // special handling.\n isWindowSupported().then(\n isSupported => {\n // If `isWindowSupported()` resolved, but returned false.\n if (!isSupported) {\n throw ERROR_FACTORY.create(ErrorCode.UNSUPPORTED_BROWSER);\n }\n },\n _ => {\n // If `isWindowSupported()` rejected.\n throw ERROR_FACTORY.create(ErrorCode.INDEXED_DB_UNSUPPORTED);\n }\n );\n return _getProvider(getModularInstance(app), 'messaging').getImmediate();\n}\n\n/**\n * Retrieves a Firebase Cloud Messaging instance.\n *\n * @returns The Firebase Cloud Messaging instance associated with the provided firebase app.\n *\n * @public\n */\nexport function getMessagingInSw(app: FirebaseApp = getApp()): Messaging {\n // Conscious decision to make this async check non-blocking during the messaging instance\n // initialization phase for performance consideration. An error would be thrown latter for\n // developer's information. Developers can then choose to import and call `isSupported` for\n // special handling.\n isSwSupported().then(\n isSupported => {\n // If `isSwSupported()` resolved, but returned false.\n if (!isSupported) {\n throw ERROR_FACTORY.create(ErrorCode.UNSUPPORTED_BROWSER);\n }\n },\n _ => {\n // If `isSwSupported()` rejected.\n throw ERROR_FACTORY.create(ErrorCode.INDEXED_DB_UNSUPPORTED);\n }\n );\n return _getProvider(getModularInstance(app), 'messaging-sw').getImmediate();\n}\n\n/**\n * Subscribes the {@link Messaging} instance to push notifications. Returns an Firebase Cloud\n * Messaging registration token that can be used to send push messages to that {@link Messaging}\n * instance.\n *\n * If a notification permission isn't already granted, this method asks the user for permission. The\n * returned promise rejects if the user does not allow the app to show notifications.\n *\n * @param messaging - The {@link Messaging} instance.\n * @param options - Provides an optional vapid key and an optinoal service worker registration\n *\n * @returns The promise resolves with an FCM registration token.\n *\n * @public\n */\nexport async function getToken(\n messaging: Messaging,\n options?: GetTokenOptions\n): Promise {\n messaging = getModularInstance(messaging);\n return _getToken(messaging as MessagingService, options);\n}\n\n/**\n * Deletes the registration token associated with this {@link Messaging} instance and unsubscribes\n * the {@link Messaging} instance from the push subscription.\n *\n * @param messaging - The {@link Messaging} instance.\n *\n * @returns The promise resolves when the token has been successfully deleted.\n *\n * @public\n */\nexport function deleteToken(messaging: Messaging): Promise {\n messaging = getModularInstance(messaging);\n return _deleteToken(messaging as MessagingService);\n}\n\n/**\n * When a push message is received and the user is currently on a page for your origin, the\n * message is passed to the page and an `onMessage()` event is dispatched with the payload of\n * the push message.\n *\n *\n * @param messaging - The {@link Messaging} instance.\n * @param nextOrObserver - This function, or observer object with `next` defined,\n * is called when a message is received and the user is currently viewing your page.\n * @returns To stop listening for messages execute this returned function.\n *\n * @public\n */\nexport function onMessage(\n messaging: Messaging,\n nextOrObserver: NextFn | Observer\n): Unsubscribe {\n messaging = getModularInstance(messaging);\n return _onMessage(messaging as MessagingService, nextOrObserver);\n}\n\n/**\n * Called when a message is received while the app is in the background. An app is considered to be\n * in the background if no active window is displayed.\n *\n * @param messaging - The {@link Messaging} instance.\n * @param nextOrObserver - This function, or observer object with `next` defined, is called when a\n * message is received and the app is currently in the background.\n *\n * @returns To stop listening for messages execute this returned function\n *\n * @public\n */\nexport function onBackgroundMessage(\n messaging: Messaging,\n nextOrObserver: NextFn | Observer\n): Unsubscribe {\n messaging = getModularInstance(messaging);\n return _onBackgroundMessage(messaging as MessagingService, nextOrObserver);\n}\n\n/**\n * Enables or disables Firebase Cloud Messaging message delivery metrics export to BigQuery. By\n * default, message delivery metrics are not exported to BigQuery. Use this method to enable or\n * disable the export at runtime.\n *\n * @param messaging - The `FirebaseMessaging` instance.\n * @param enable - Whether Firebase Cloud Messaging should export message delivery metrics to\n * BigQuery.\n *\n * @public\n */\nexport function experimentalSetDeliveryMetricsExportedToBigQueryEnabled(\n messaging: Messaging,\n enable: boolean\n): void {\n messaging = getModularInstance(messaging);\n return _setDeliveryMetricsExportedToBigQueryEnabled(messaging, enable);\n}\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport '@firebase/installations';\n\nimport { Messaging } from './interfaces/public-types';\nimport { registerMessagingInSw } from './helpers/register';\n\nexport * from './interfaces/public-types';\nexport {\n onBackgroundMessage,\n getMessagingInSw as getMessaging,\n experimentalSetDeliveryMetricsExportedToBigQueryEnabled\n} from './api';\nexport { isSwSupported as isSupported } from './api/isSupported';\n\ndeclare module '@firebase/component' {\n interface NameServiceMapping {\n 'messaging-sw': Messaging;\n }\n}\n\nregisterMessagingInSw();\n", "import { initializeApp } from 'firebase/app';\nimport {\n experimentalSetDeliveryMetricsExportedToBigQueryEnabled,\n getMessaging,\n isSupported,\n onBackgroundMessage,\n} from 'firebase/messaging/sw';\n\nself.addEventListener('install', (event) => {\n console.log(self);\n console.log(event);\n});\n\nconst app = initializeApp({\n apiKey: 'AIzaSyAgUhHU8wSJgO5MVNy95tMT07NEjzMOfz0',\n authDomain: 'react-native-firebase-testing.firebaseapp.com',\n databaseURL: 'https://react-native-firebase-testing.firebaseio.com',\n projectId: 'react-native-firebase-testing',\n storageBucket: 'react-native-firebase-testing.appspot.com',\n messagingSenderId: '448618578101',\n appId: '1:448618578101:web:ecaffe2bc4511738',\n});\n\nisSupported().then((isSupported) => {\n if (isSupported) {\n const messaging = getMessaging(app);\n\n experimentalSetDeliveryMetricsExportedToBigQueryEnabled(messaging, true);\n\n console.log('experimental working');\n\n onBackgroundMessage(messaging, ({ notification: notification }) => {\n const { title, body, image } = notification ?? {};\n\n if (!title) {\n return;\n }\n\n self.registration.showNotification(title, {\n body,\n icon: image || '/assets/icons/icon-72x72.png',\n });\n });\n }\n});\n"], + "mappings": "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", + "names": ["stringToByteArray", "str", "out", "p", "i", "c", "byteArrayToString", "bytes", "pos", "c1", "c2", "c3", "c4", "base64", "input", "webSafe", "byteToCharMap", "output", "byte1", "haveByte2", "byte2", "haveByte3", "byte3", "outByte1", "outByte2", "outByte3", "outByte4", "charToByteMap", "byte4", "base64Encode", "utf8Bytes", "base64urlEncodeWithoutPadding", "Deferred", "resolve", "reject", "callback", "error", "value", "isIndexedDBAvailable", "validateIndexedDBOpenable", "resolve", "reject", "preExist", "DB_CHECK_NAME", "request", "_a", "error", "ERROR_NAME", "FirebaseError", "code", "message", "customData", "ErrorFactory", "service", "serviceName", "errors", "data", "fullCode", "template", "replaceTemplate", "fullMessage", "PATTERN", "_", "key", "value", "deepEqual", "a", "b", "aKeys", "bKeys", "k", "aProp", "bProp", "isObject", "thing", "MAX_VALUE_MILLIS", "getModularInstance", "service", "Component", "name", "instanceFactory", "type", "mode", "multipleInstances", "props", "callback", "DEFAULT_ENTRY_NAME", "Provider", "container", "identifier", "normalizedIdentifier", "deferred", "Deferred", "instance", "options", "optional", "_a", "e", "component", "isComponentEager", "instanceIdentifier", "instanceDeferred", "services", "service", "opts", "normalizedDeferredIdentifier", "existingCallbacks", "existingInstance", "callbacks", "normalizeIdentifierForFactory", "ComponentContainer", "provider", "instances", "LogLevel", "levelStringToEnum", "defaultLogLevel", "ConsoleMethod", "defaultLogHandler", "instance", "logType", "args", "now", "method", "Logger", "name", "val", "instanceOfAny", "object", "constructors", "c", "idbProxyableTypes", "cursorAdvanceMethods", "getIdbProxyableTypes", "getCursorAdvanceMethods", "cursorRequestMap", "transactionDoneMap", "transactionStoreNamesMap", "transformCache", "reverseTransformCache", "promisifyRequest", "request", "promise", "resolve", "reject", "unlisten", "success", "error", "wrap", "value", "cacheDonePromiseForTransaction", "tx", "done", "complete", "idbProxyTraps", "target", "prop", "receiver", "replaceTraps", "callback", "wrapFunction", "func", "storeNames", "args", "unwrap", "transformCachableValue", "newValue", "openDB", "name", "version", "blocked", "upgrade", "blocking", "terminated", "request", "openPromise", "wrap", "event", "db", "deleteDB", "readMethods", "writeMethods", "cachedMethods", "getMethod", "target", "prop", "targetFuncName", "useIndex", "isWrite", "method", "storeName", "args", "tx", "replaceTraps", "oldTraps", "receiver", "PlatformLoggerServiceImpl", "container", "provider", "isVersionServiceProvider", "service", "logString", "component", "logger", "Logger", "DEFAULT_ENTRY_NAME", "PLATFORM_LOG_STRING", "appName", "appCompatName", "analyticsName", "analyticsCompatName", "appCheckName", "appCheckCompatName", "authName", "authCompatName", "databaseName", "databaseCompatName", "functionsName", "functionsCompatName", "installationsName", "installationsCompatName", "messagingName", "messagingCompatName", "performanceName", "performanceCompatName", "remoteConfigName", "remoteConfigCompatName", "storageName", "storageCompatName", "firestoreName", "firestoreCompatName", "packageName", "_apps", "_components", "_addComponent", "app", "component", "e", "logger", "_registerComponent", "component", "componentName", "_components", "logger", "app", "_apps", "_addComponent", "_getProvider", "name", "heartbeatController", "ERRORS", "ERROR_FACTORY", "ErrorFactory", "FirebaseAppImpl", "options", "config", "container", "Component", "val", "initializeApp", "options", "rawConfig", "config", "DEFAULT_ENTRY_NAME", "name", "ERROR_FACTORY", "existingApp", "_apps", "deepEqual", "container", "ComponentContainer", "component", "_components", "newApp", "FirebaseAppImpl", "getApp", "app", "registerVersion", "libraryKeyOrName", "version", "variant", "library", "_a", "PLATFORM_LOG_STRING", "libraryMismatch", "versionMismatch", "warning", "logger", "_registerComponent", "Component", "DB_NAME", "DB_VERSION", "STORE_NAME", "dbPromise", "getDbPromise", "openDB", "db", "oldVersion", "ERROR_FACTORY", "readHeartbeatsFromIndexedDB", "app", "computeKey", "e", "FirebaseError", "logger", "idbGetError", "_a", "writeHeartbeatsToIndexedDB", "heartbeatObject", "tx", "MAX_HEADER_BYTES", "STORED_HEARTBEAT_RETENTION_MAX_MILLIS", "HeartbeatServiceImpl", "container", "HeartbeatStorageImpl", "result", "agent", "date", "getUTCDateString", "singleDateHeartbeat", "hbTimestamp", "heartbeatsToSend", "unsentEntries", "extractHeartbeatsForHeader", "headerString", "base64urlEncodeWithoutPadding", "heartbeatsCache", "maxSize", "heartbeatEntry", "hb", "countBytes", "isIndexedDBAvailable", "validateIndexedDBOpenable", "heartbeatsObject", "existingHeartbeatsObject", "registerCoreComponents", "variant", "_registerComponent", "Component", "PlatformLoggerServiceImpl", "registerVersion", "name", "version", "registerVersion", "name", "version", "PENDING_TIMEOUT_MS", "PACKAGE_VERSION", "version", "INTERNAL_AUTH_VERSION", "INSTALLATIONS_API_URL", "TOKEN_EXPIRATION_BUFFER", "SERVICE", "SERVICE_NAME", "ERROR_DESCRIPTION_MAP", "ERROR_FACTORY", "ErrorFactory", "isServerError", "error", "FirebaseError", "getInstallationsEndpoint", "projectId", "extractAuthTokenInfoFromResponse", "response", "getExpiresInFromResponseExpiresIn", "getErrorFromResponse", "requestName", "errorData", "getHeaders", "apiKey", "getHeadersWithAuth", "appConfig", "refreshToken", "headers", "getAuthorizationHeader", "retryIfServerError", "fn", "result", "responseExpiresIn", "createInstallationRequest", "heartbeatServiceProvider", "fid", "endpoint", "heartbeatService", "heartbeatsHeader", "body", "request", "responseValue", "sleep", "ms", "resolve", "bufferToBase64UrlSafe", "array", "VALID_FID_PATTERN", "INVALID_FID", "generateFid", "fidByteArray", "encode", "getKey", "fidChangeCallbacks", "fidChanged", "key", "callFidChangeCallbacks", "broadcastFidChange", "callFidChangeCallbacks", "key", "fid", "callbacks", "fidChangeCallbacks", "callback", "broadcastFidChange", "channel", "getBroadcastChannel", "closeBroadcastChannel", "broadcastChannel", "DATABASE_NAME", "DATABASE_VERSION", "OBJECT_STORE_NAME", "dbPromise", "getDbPromise", "openDB", "db", "oldVersion", "set", "appConfig", "value", "getKey", "tx", "objectStore", "oldValue", "fidChanged", "remove", "update", "updateFn", "store", "newValue", "getInstallationEntry", "installations", "registrationPromise", "installationEntry", "oldEntry", "updateOrCreateInstallationEntry", "entryWithPromise", "triggerRegistrationIfNecessary", "INVALID_FID", "entry", "generateFid", "clearTimedOutRequest", "registrationPromiseWithError", "ERROR_FACTORY", "inProgressEntry", "registerInstallation", "waitUntilFidRegistration", "registeredInstallationEntry", "createInstallationRequest", "e", "isServerError", "updateInstallationRequest", "sleep", "hasInstallationRequestTimedOut", "PENDING_TIMEOUT_MS", "generateAuthTokenRequest", "heartbeatServiceProvider", "endpoint", "getGenerateAuthTokenEndpoint", "headers", "getHeadersWithAuth", "heartbeatService", "heartbeatsHeader", "body", "PACKAGE_VERSION", "request", "response", "retryIfServerError", "responseValue", "extractAuthTokenInfoFromResponse", "getErrorFromResponse", "getInstallationsEndpoint", "refreshAuthToken", "forceRefresh", "tokenPromise", "isEntryRegistered", "oldAuthToken", "isAuthTokenValid", "waitUntilAuthTokenRequest", "makeAuthTokenRequestInProgressEntry", "fetchAuthTokenFromServer", "updateAuthTokenRequest", "authToken", "hasAuthTokenRequestTimedOut", "updatedInstallationEntry", "isAuthTokenExpired", "now", "TOKEN_EXPIRATION_BUFFER", "inProgressAuthToken", "getId", "installationsImpl", "getToken", "completeInstallationRegistration", "extractAppConfig", "app", "getMissingValueError", "configKeys", "keyName", "valueName", "ERROR_FACTORY", "INSTALLATIONS_NAME", "INSTALLATIONS_NAME_INTERNAL", "publicFactory", "container", "appConfig", "heartbeatServiceProvider", "_getProvider", "internalFactory", "installations", "getId", "forceRefresh", "getToken", "registerInstallations", "_registerComponent", "Component", "registerVersion", "name", "version", "DEFAULT_VAPID_KEY", "ENDPOINT", "FCM_MSG", "CONSOLE_CAMPAIGN_ID", "SDK_PLATFORM_WEB", "EVENT_MESSAGE_DELIVERED", "MessageType", "arrayToBase64", "array", "uint8Array", "base64ToArray", "base64String", "padding", "base64", "rawData", "outputArray", "i", "OLD_DB_NAME", "OLD_DB_VERSION", "OLD_OBJECT_STORE_NAME", "migrateOldDatabase", "senderId", "db", "tokenDetails", "openDB", "oldVersion", "newVersion", "upgradeTransaction", "objectStore", "value", "oldDetails", "_a", "deleteDB", "checkTokenDetails", "subscriptionOptions", "DATABASE_NAME", "DATABASE_VERSION", "OBJECT_STORE_NAME", "dbPromise", "getDbPromise", "upgradeDb", "dbGet", "firebaseDependencies", "key", "getKey", "oldTokenDetails", "dbSet", "tx", "dbRemove", "appConfig", "ERROR_MAP", "ERROR_FACTORY", "ErrorFactory", "requestGetToken", "headers", "getHeaders", "body", "getBody", "subscribeOptions", "responseData", "getEndpoint", "err", "message", "requestUpdateToken", "updateOptions", "requestDeleteToken", "token", "unsubscribeOptions", "projectId", "installations", "authToken", "p256dh", "auth", "endpoint", "vapidKey", "TOKEN_EXPIRATION_MS", "getTokenInternal", "messaging", "pushSubscription", "getPushSubscription", "isTokenValid", "updateToken", "e", "getNewToken", "deleteTokenInternal", "updatedToken", "updatedTokenDetails", "swRegistration", "subscription", "dbOptions", "currentOptions", "isVapidKeyEqual", "isEndpointEqual", "isAuthEqual", "isP256dhEqual", "externalizePayload", "internalPayload", "payload", "propagateNotificationPayload", "propagateDataPayload", "propagateFcmOptions", "messagePayloadInternal", "title", "image", "link", "_c", "_b", "_d", "analyticsLabel", "_e", "isConsoleMessage", "data", "sleep", "ms", "resolve", "_mergeStrings", "stageLog", "fcmEvent", "createFcmEvent", "createAndEnqueueLogEvent", "fid", "logEvent", "s1", "s2", "resultArray", "onSubChange", "event", "newSubscription", "onPush", "getMessagePayloadInternal", "clientList", "getClientList", "hasVisibleClients", "sendMessagePayloadInternalToWindows", "showNotification", "wrapInternalPayload", "onNotificationClick", "getLink", "url", "originUrl", "client", "getWindowClient", "wrappedInternalPayload", "clientUrl", "notificationPayloadInternal", "actions", "maxActions", "extractAppConfig", "app", "getMissingValueError", "configKeys", "options", "keyName", "valueName", "MessagingService", "analyticsProvider", "SwMessagingFactory", "container", "registerMessagingInSw", "_registerComponent", "Component", "isSwSupported", "isIndexedDBAvailable", "validateIndexedDBOpenable", "onBackgroundMessage", "nextOrObserver", "_setDeliveryMetricsExportedToBigQueryEnabled", "enable", "getMessagingInSw", "getApp", "isSupported", "_", "_getProvider", "getModularInstance", "_onBackgroundMessage", "experimentalSetDeliveryMetricsExportedToBigQueryEnabled", "event", "app", "initializeApp", "isSwSupported", "isSupported", "messaging", "getMessagingInSw", "experimentalSetDeliveryMetricsExportedToBigQueryEnabled", "onBackgroundMessage", "notification", "title", "body", "image"] +} diff --git a/packages/firebase_messaging/firebase_messaging/example/web/index.html b/packages/firebase_messaging/firebase_messaging/example/web/index.html index 9b9c5d01afdd..4397b3d6e868 100644 --- a/packages/firebase_messaging/firebase_messaging/example/web/index.html +++ b/packages/firebase_messaging/firebase_messaging/example/web/index.html @@ -1,39 +1,40 @@ + + + example + - - - example - + + - - - - - + // If service worker doesn't succeed in a reasonable amount of time, + // fallback to plaint + diff --git a/packages/firebase_messaging/firebase_messaging/lib/src/messaging.dart b/packages/firebase_messaging/firebase_messaging/lib/src/messaging.dart index 049faf763a8b..c1bd9ce38f4b 100644 --- a/packages/firebase_messaging/firebase_messaging/lib/src/messaging.dart +++ b/packages/firebase_messaging/firebase_messaging/lib/src/messaging.dart @@ -229,9 +229,11 @@ class FirebaseMessaging extends FirebasePluginPlatform { return _delegate.setAutoInitEnabled(enabled); } - /// Enables or disables Firebase Cloud Messaging message delivery metrics export to BigQuery. + /// Enables or disables Firebase Cloud Messaging message delivery metrics export to BigQuery for Android. /// - /// On iOS, you need to follow [this guide](https://firebase.google.com/docs/cloud-messaging/understand-delivery?platform=ios#enable_delivery_data_export_for_background_notifications) in order to export metrics to BigQuery. + /// On iOS, you need to follow [this guide](https://firebase.google.com/docs/cloud-messaging/understand-delivery?platform=ios#enable_delivery_data_export_for_background_notifications) + /// in order to export metrics to BigQuery. + /// On Web, you need to setup a [service worker](https://firebase.google.com/docs/cloud-messaging/js/client) and call `experimentalSetDeliveryMetricsExportedToBigQueryEnabled(messaging, true)` Future setDeliveryMetricsExportToBigQuery(bool enabled) async { return _delegate.setDeliveryMetricsExportToBigQuery(enabled); } diff --git a/packages/firebase_messaging/firebase_messaging_web/lib/firebase_messaging_web.dart b/packages/firebase_messaging/firebase_messaging_web/lib/firebase_messaging_web.dart index 142d703e3921..c9e607d74929 100644 --- a/packages/firebase_messaging/firebase_messaging_web/lib/firebase_messaging_web.dart +++ b/packages/firebase_messaging/firebase_messaging_web/lib/firebase_messaging_web.dart @@ -118,21 +118,6 @@ class FirebaseMessagingWeb extends FirebaseMessagingPlatform { ); } - @override - Future setDeliveryMetricsExportToBigQuery(bool enabled) async { - _delegate; - - if (!_initialized) { - // no-op for unsupported browsers - return; - } - - return convertWebExceptions( - () => _delegate - .experimentalSetDeliveryMetricsExportedToBigQueryEnabled(enabled), - ); - } - @override Stream get onTokenRefresh { // onTokenRefresh is deprecated on web, however since this is a non-critical diff --git a/packages/firebase_messaging/firebase_messaging_web/lib/src/interop/messaging.dart b/packages/firebase_messaging/firebase_messaging_web/lib/src/interop/messaging.dart index 8df16b352bba..336dbecf6e8e 100644 --- a/packages/firebase_messaging/firebase_messaging_web/lib/src/interop/messaging.dart +++ b/packages/firebase_messaging/firebase_messaging_web/lib/src/interop/messaging.dart @@ -48,20 +48,6 @@ class Messaging extends JsObjectWrapper { ? null : messaging_interop.GetTokenOptions(vapidKey: vapidKey))); - /// Enables or disables Firebase Cloud Messaging message delivery metrics export to BigQuery. - /// By default, message delivery metrics are not exported to BigQuery. - /// Use this method to enable or disable the export at runtime. - Future experimentalSetDeliveryMetricsExportedToBigQueryEnabled( - bool enabled, - ) => - handleThenable( - messaging_interop - .experimentalSetDeliveryMetricsExportedToBigQueryEnabled( - jsObject, - enabled, - ), - ); - // ignore: close_sinks StreamController? _onMessageController; diff --git a/packages/firebase_messaging/firebase_messaging_web/lib/src/interop/messaging_interop.dart b/packages/firebase_messaging/firebase_messaging_web/lib/src/interop/messaging_interop.dart index d2848c63650c..14b51c5a4bcb 100644 --- a/packages/firebase_messaging/firebase_messaging_web/lib/src/interop/messaging_interop.dart +++ b/packages/firebase_messaging/firebase_messaging_web/lib/src/interop/messaging_interop.dart @@ -21,11 +21,6 @@ external PromiseJsImpl deleteToken(MessagingJsImpl messaging); external PromiseJsImpl getToken( MessagingJsImpl messaging, GetTokenOptions? getTokenOptions); -@JS() -external PromiseJsImpl - experimentalSetDeliveryMetricsExportedToBigQueryEnabled( - MessagingJsImpl messaging, bool enabled); - @JS('isSupported') external PromiseJsImpl isSupported(); From 53d68dd5238b910062e2e49d55b6a1e0188f0722 Mon Sep 17 00:00:00 2001 From: Guillaume Bernos Date: Wed, 5 Oct 2022 09:21:05 +0200 Subject: [PATCH 07/13] feat(messaging): export to BigQuery on web --- .../bundled-service-worker/firebase-messaging-sw.ts | 4 +++- .../example/bundled-service-worker/tsconfig.json | 8 ++++++++ .../example/web/firebase-messaging-sw.js.map | 4 ++-- 3 files changed, 13 insertions(+), 3 deletions(-) create mode 100644 packages/firebase_messaging/firebase_messaging/example/bundled-service-worker/tsconfig.json diff --git a/packages/firebase_messaging/firebase_messaging/example/bundled-service-worker/firebase-messaging-sw.ts b/packages/firebase_messaging/firebase_messaging/example/bundled-service-worker/firebase-messaging-sw.ts index b8e37e594ecb..16d1bde78c19 100644 --- a/packages/firebase_messaging/firebase_messaging/example/bundled-service-worker/firebase-messaging-sw.ts +++ b/packages/firebase_messaging/firebase_messaging/example/bundled-service-worker/firebase-messaging-sw.ts @@ -3,9 +3,11 @@ import { experimentalSetDeliveryMetricsExportedToBigQueryEnabled, getMessaging, isSupported, - onBackgroundMessage, + onBackgroundMessage } from 'firebase/messaging/sw'; +declare var self: ServiceWorkerGlobalScope; + self.addEventListener('install', (event) => { console.log(self); console.log(event); diff --git a/packages/firebase_messaging/firebase_messaging/example/bundled-service-worker/tsconfig.json b/packages/firebase_messaging/firebase_messaging/example/bundled-service-worker/tsconfig.json new file mode 100644 index 000000000000..814f3a72a650 --- /dev/null +++ b/packages/firebase_messaging/firebase_messaging/example/bundled-service-worker/tsconfig.json @@ -0,0 +1,8 @@ +{ + "compilerOptions": { + "lib": [ + "webworker", + "es6" + ] + } +} \ No newline at end of file diff --git a/packages/firebase_messaging/firebase_messaging/example/web/firebase-messaging-sw.js.map b/packages/firebase_messaging/firebase_messaging/example/web/firebase-messaging-sw.js.map index cffb6ab13552..094a11115c4e 100644 --- a/packages/firebase_messaging/firebase_messaging/example/web/firebase-messaging-sw.js.map +++ b/packages/firebase_messaging/firebase_messaging/example/web/firebase-messaging-sw.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../bundled-service-worker/node_modules/@firebase/util/src/constants.ts", "../bundled-service-worker/node_modules/@firebase/util/src/assert.ts", "../bundled-service-worker/node_modules/@firebase/util/src/crypt.ts", "../bundled-service-worker/node_modules/@firebase/util/src/deepCopy.ts", "../bundled-service-worker/node_modules/@firebase/util/src/deferred.ts", "../bundled-service-worker/node_modules/@firebase/util/src/emulator.ts", "../bundled-service-worker/node_modules/@firebase/util/src/environment.ts", "../bundled-service-worker/node_modules/@firebase/util/src/errors.ts", "../bundled-service-worker/node_modules/@firebase/util/src/json.ts", "../bundled-service-worker/node_modules/@firebase/util/src/jwt.ts", "../bundled-service-worker/node_modules/@firebase/util/src/obj.ts", "../bundled-service-worker/node_modules/@firebase/util/src/promise.ts", "../bundled-service-worker/node_modules/@firebase/util/src/query.ts", "../bundled-service-worker/node_modules/@firebase/util/src/sha1.ts", "../bundled-service-worker/node_modules/@firebase/util/src/subscribe.ts", "../bundled-service-worker/node_modules/@firebase/util/src/validation.ts", "../bundled-service-worker/node_modules/@firebase/util/src/utf8.ts", "../bundled-service-worker/node_modules/@firebase/util/src/uuid.ts", "../bundled-service-worker/node_modules/@firebase/util/src/exponential_backoff.ts", "../bundled-service-worker/node_modules/@firebase/util/src/formatters.ts", "../bundled-service-worker/node_modules/@firebase/util/src/compat.ts", "../bundled-service-worker/node_modules/@firebase/component/src/component.ts", "../bundled-service-worker/node_modules/@firebase/component/src/constants.ts", "../bundled-service-worker/node_modules/@firebase/component/src/provider.ts", "../bundled-service-worker/node_modules/@firebase/component/src/component_container.ts", "../bundled-service-worker/node_modules/@firebase/logger/src/logger.ts", "../bundled-service-worker/node_modules/idb/build/wrap-idb-value.js", "../bundled-service-worker/node_modules/idb/build/index.js", "../bundled-service-worker/node_modules/@firebase/app/src/platformLoggerService.ts", "../bundled-service-worker/node_modules/@firebase/app/src/logger.ts", "../bundled-service-worker/node_modules/@firebase/app/src/constants.ts", "../bundled-service-worker/node_modules/@firebase/app/src/internal.ts", "../bundled-service-worker/node_modules/@firebase/app/src/errors.ts", "../bundled-service-worker/node_modules/@firebase/app/src/firebaseApp.ts", "../bundled-service-worker/node_modules/@firebase/app/src/api.ts", "../bundled-service-worker/node_modules/@firebase/app/src/indexeddb.ts", "../bundled-service-worker/node_modules/@firebase/app/src/heartbeatService.ts", "../bundled-service-worker/node_modules/@firebase/app/src/registerCoreComponents.ts", "../bundled-service-worker/node_modules/@firebase/app/src/index.ts", "../bundled-service-worker/node_modules/firebase/app/index.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/util/constants.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/util/errors.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/functions/common.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/functions/create-installation-request.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/util/sleep.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/helpers/buffer-to-base64-url-safe.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/helpers/generate-fid.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/util/get-key.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/helpers/fid-changed.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/helpers/idb-manager.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/helpers/get-installation-entry.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/functions/generate-auth-token-request.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/helpers/refresh-auth-token.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/api/get-id.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/api/get-token.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/functions/delete-installation-request.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/api/delete-installations.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/api/on-id-change.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/api/get-installations.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/helpers/extract-app-config.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/functions/config.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/index.ts", "../bundled-service-worker/node_modules/@firebase/messaging/src/util/constants.ts", "../bundled-service-worker/node_modules/@firebase/messaging/src/interfaces/internal-message-payload.ts", "../bundled-service-worker/node_modules/@firebase/messaging/src/helpers/array-base64-translator.ts", "../bundled-service-worker/node_modules/@firebase/messaging/src/helpers/migrate-old-database.ts", "../bundled-service-worker/node_modules/@firebase/messaging/src/internals/idb-manager.ts", "../bundled-service-worker/node_modules/@firebase/messaging/src/util/errors.ts", "../bundled-service-worker/node_modules/@firebase/messaging/src/internals/requests.ts", "../bundled-service-worker/node_modules/@firebase/messaging/src/internals/token-manager.ts", "../bundled-service-worker/node_modules/@firebase/messaging/src/helpers/externalizePayload.ts", "../bundled-service-worker/node_modules/@firebase/messaging/src/helpers/is-console-message.ts", "../bundled-service-worker/node_modules/@firebase/messaging/src/helpers/sleep.ts", "../bundled-service-worker/node_modules/@firebase/messaging/src/helpers/logToFirelog.ts", "../bundled-service-worker/node_modules/@firebase/messaging/src/listeners/sw-listeners.ts", "../bundled-service-worker/node_modules/@firebase/messaging/src/helpers/extract-app-config.ts", "../bundled-service-worker/node_modules/@firebase/messaging/src/messaging-service.ts", "../bundled-service-worker/node_modules/@firebase/messaging/src/helpers/register.ts", "../bundled-service-worker/node_modules/@firebase/messaging/src/api/isSupported.ts", "../bundled-service-worker/node_modules/@firebase/messaging/src/api/onBackgroundMessage.ts", "../bundled-service-worker/node_modules/@firebase/messaging/src/api/setDeliveryMetricsExportedToBigQueryEnabled.ts", "../bundled-service-worker/node_modules/@firebase/messaging/src/api.ts", "../bundled-service-worker/node_modules/@firebase/messaging/src/index.sw.ts", "../bundled-service-worker/firebase-messaging-sw.ts"], - "sourcesContent": ["/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * @fileoverview Firebase constants. Some of these (@defines) can be overridden at compile-time.\n */\n\nexport const CONSTANTS = {\n /**\n * @define {boolean} Whether this is the client Node.js SDK.\n */\n NODE_CLIENT: false,\n /**\n * @define {boolean} Whether this is the Admin Node.js SDK.\n */\n NODE_ADMIN: false,\n\n /**\n * Firebase SDK Version\n */\n SDK_VERSION: '${JSCORE_VERSION}'\n};\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { CONSTANTS } from './constants';\n\n/**\n * Throws an error if the provided assertion is falsy\n */\nexport const assert = function (assertion: unknown, message: string): void {\n if (!assertion) {\n throw assertionError(message);\n }\n};\n\n/**\n * Returns an Error object suitable for throwing.\n */\nexport const assertionError = function (message: string): Error {\n return new Error(\n 'Firebase Database (' +\n CONSTANTS.SDK_VERSION +\n ') INTERNAL ASSERT FAILED: ' +\n message\n );\n};\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nconst stringToByteArray = function (str: string): number[] {\n // TODO(user): Use native implementations if/when available\n const out: number[] = [];\n let p = 0;\n for (let i = 0; i < str.length; i++) {\n let c = str.charCodeAt(i);\n if (c < 128) {\n out[p++] = c;\n } else if (c < 2048) {\n out[p++] = (c >> 6) | 192;\n out[p++] = (c & 63) | 128;\n } else if (\n (c & 0xfc00) === 0xd800 &&\n i + 1 < str.length &&\n (str.charCodeAt(i + 1) & 0xfc00) === 0xdc00\n ) {\n // Surrogate Pair\n c = 0x10000 + ((c & 0x03ff) << 10) + (str.charCodeAt(++i) & 0x03ff);\n out[p++] = (c >> 18) | 240;\n out[p++] = ((c >> 12) & 63) | 128;\n out[p++] = ((c >> 6) & 63) | 128;\n out[p++] = (c & 63) | 128;\n } else {\n out[p++] = (c >> 12) | 224;\n out[p++] = ((c >> 6) & 63) | 128;\n out[p++] = (c & 63) | 128;\n }\n }\n return out;\n};\n\n/**\n * Turns an array of numbers into the string given by the concatenation of the\n * characters to which the numbers correspond.\n * @param bytes Array of numbers representing characters.\n * @return Stringification of the array.\n */\nconst byteArrayToString = function (bytes: number[]): string {\n // TODO(user): Use native implementations if/when available\n const out: string[] = [];\n let pos = 0,\n c = 0;\n while (pos < bytes.length) {\n const c1 = bytes[pos++];\n if (c1 < 128) {\n out[c++] = String.fromCharCode(c1);\n } else if (c1 > 191 && c1 < 224) {\n const c2 = bytes[pos++];\n out[c++] = String.fromCharCode(((c1 & 31) << 6) | (c2 & 63));\n } else if (c1 > 239 && c1 < 365) {\n // Surrogate Pair\n const c2 = bytes[pos++];\n const c3 = bytes[pos++];\n const c4 = bytes[pos++];\n const u =\n (((c1 & 7) << 18) | ((c2 & 63) << 12) | ((c3 & 63) << 6) | (c4 & 63)) -\n 0x10000;\n out[c++] = String.fromCharCode(0xd800 + (u >> 10));\n out[c++] = String.fromCharCode(0xdc00 + (u & 1023));\n } else {\n const c2 = bytes[pos++];\n const c3 = bytes[pos++];\n out[c++] = String.fromCharCode(\n ((c1 & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)\n );\n }\n }\n return out.join('');\n};\n\ninterface Base64 {\n byteToCharMap_: { [key: number]: string } | null;\n charToByteMap_: { [key: string]: number } | null;\n byteToCharMapWebSafe_: { [key: number]: string } | null;\n charToByteMapWebSafe_: { [key: string]: number } | null;\n ENCODED_VALS_BASE: string;\n readonly ENCODED_VALS: string;\n readonly ENCODED_VALS_WEBSAFE: string;\n HAS_NATIVE_SUPPORT: boolean;\n encodeByteArray(input: number[] | Uint8Array, webSafe?: boolean): string;\n encodeString(input: string, webSafe?: boolean): string;\n decodeString(input: string, webSafe: boolean): string;\n decodeStringToByteArray(input: string, webSafe: boolean): number[];\n init_(): void;\n}\n\n// We define it as an object literal instead of a class because a class compiled down to es5 can't\n// be treeshaked. https://github.com/rollup/rollup/issues/1691\n// Static lookup maps, lazily populated by init_()\nexport const base64: Base64 = {\n /**\n * Maps bytes to characters.\n */\n byteToCharMap_: null,\n\n /**\n * Maps characters to bytes.\n */\n charToByteMap_: null,\n\n /**\n * Maps bytes to websafe characters.\n * @private\n */\n byteToCharMapWebSafe_: null,\n\n /**\n * Maps websafe characters to bytes.\n * @private\n */\n charToByteMapWebSafe_: null,\n\n /**\n * Our default alphabet, shared between\n * ENCODED_VALS and ENCODED_VALS_WEBSAFE\n */\n ENCODED_VALS_BASE:\n 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + 'abcdefghijklmnopqrstuvwxyz' + '0123456789',\n\n /**\n * Our default alphabet. Value 64 (=) is special; it means \"nothing.\"\n */\n get ENCODED_VALS() {\n return this.ENCODED_VALS_BASE + '+/=';\n },\n\n /**\n * Our websafe alphabet.\n */\n get ENCODED_VALS_WEBSAFE() {\n return this.ENCODED_VALS_BASE + '-_.';\n },\n\n /**\n * Whether this browser supports the atob and btoa functions. This extension\n * started at Mozilla but is now implemented by many browsers. We use the\n * ASSUME_* variables to avoid pulling in the full useragent detection library\n * but still allowing the standard per-browser compilations.\n *\n */\n HAS_NATIVE_SUPPORT: typeof atob === 'function',\n\n /**\n * Base64-encode an array of bytes.\n *\n * @param input An array of bytes (numbers with\n * value in [0, 255]) to encode.\n * @param webSafe Boolean indicating we should use the\n * alternative alphabet.\n * @return The base64 encoded string.\n */\n encodeByteArray(input: number[] | Uint8Array, webSafe?: boolean): string {\n if (!Array.isArray(input)) {\n throw Error('encodeByteArray takes an array as a parameter');\n }\n\n this.init_();\n\n const byteToCharMap = webSafe\n ? this.byteToCharMapWebSafe_!\n : this.byteToCharMap_!;\n\n const output = [];\n\n for (let i = 0; i < input.length; i += 3) {\n const byte1 = input[i];\n const haveByte2 = i + 1 < input.length;\n const byte2 = haveByte2 ? input[i + 1] : 0;\n const haveByte3 = i + 2 < input.length;\n const byte3 = haveByte3 ? input[i + 2] : 0;\n\n const outByte1 = byte1 >> 2;\n const outByte2 = ((byte1 & 0x03) << 4) | (byte2 >> 4);\n let outByte3 = ((byte2 & 0x0f) << 2) | (byte3 >> 6);\n let outByte4 = byte3 & 0x3f;\n\n if (!haveByte3) {\n outByte4 = 64;\n\n if (!haveByte2) {\n outByte3 = 64;\n }\n }\n\n output.push(\n byteToCharMap[outByte1],\n byteToCharMap[outByte2],\n byteToCharMap[outByte3],\n byteToCharMap[outByte4]\n );\n }\n\n return output.join('');\n },\n\n /**\n * Base64-encode a string.\n *\n * @param input A string to encode.\n * @param webSafe If true, we should use the\n * alternative alphabet.\n * @return The base64 encoded string.\n */\n encodeString(input: string, webSafe?: boolean): string {\n // Shortcut for Mozilla browsers that implement\n // a native base64 encoder in the form of \"btoa/atob\"\n if (this.HAS_NATIVE_SUPPORT && !webSafe) {\n return btoa(input);\n }\n return this.encodeByteArray(stringToByteArray(input), webSafe);\n },\n\n /**\n * Base64-decode a string.\n *\n * @param input to decode.\n * @param webSafe True if we should use the\n * alternative alphabet.\n * @return string representing the decoded value.\n */\n decodeString(input: string, webSafe: boolean): string {\n // Shortcut for Mozilla browsers that implement\n // a native base64 encoder in the form of \"btoa/atob\"\n if (this.HAS_NATIVE_SUPPORT && !webSafe) {\n return atob(input);\n }\n return byteArrayToString(this.decodeStringToByteArray(input, webSafe));\n },\n\n /**\n * Base64-decode a string.\n *\n * In base-64 decoding, groups of four characters are converted into three\n * bytes. If the encoder did not apply padding, the input length may not\n * be a multiple of 4.\n *\n * In this case, the last group will have fewer than 4 characters, and\n * padding will be inferred. If the group has one or two characters, it decodes\n * to one byte. If the group has three characters, it decodes to two bytes.\n *\n * @param input Input to decode.\n * @param webSafe True if we should use the web-safe alphabet.\n * @return bytes representing the decoded value.\n */\n decodeStringToByteArray(input: string, webSafe: boolean): number[] {\n this.init_();\n\n const charToByteMap = webSafe\n ? this.charToByteMapWebSafe_!\n : this.charToByteMap_!;\n\n const output: number[] = [];\n\n for (let i = 0; i < input.length; ) {\n const byte1 = charToByteMap[input.charAt(i++)];\n\n const haveByte2 = i < input.length;\n const byte2 = haveByte2 ? charToByteMap[input.charAt(i)] : 0;\n ++i;\n\n const haveByte3 = i < input.length;\n const byte3 = haveByte3 ? charToByteMap[input.charAt(i)] : 64;\n ++i;\n\n const haveByte4 = i < input.length;\n const byte4 = haveByte4 ? charToByteMap[input.charAt(i)] : 64;\n ++i;\n\n if (byte1 == null || byte2 == null || byte3 == null || byte4 == null) {\n throw Error();\n }\n\n const outByte1 = (byte1 << 2) | (byte2 >> 4);\n output.push(outByte1);\n\n if (byte3 !== 64) {\n const outByte2 = ((byte2 << 4) & 0xf0) | (byte3 >> 2);\n output.push(outByte2);\n\n if (byte4 !== 64) {\n const outByte3 = ((byte3 << 6) & 0xc0) | byte4;\n output.push(outByte3);\n }\n }\n }\n\n return output;\n },\n\n /**\n * Lazy static initialization function. Called before\n * accessing any of the static map variables.\n * @private\n */\n init_() {\n if (!this.byteToCharMap_) {\n this.byteToCharMap_ = {};\n this.charToByteMap_ = {};\n this.byteToCharMapWebSafe_ = {};\n this.charToByteMapWebSafe_ = {};\n\n // We want quick mappings back and forth, so we precompute two maps.\n for (let i = 0; i < this.ENCODED_VALS.length; i++) {\n this.byteToCharMap_[i] = this.ENCODED_VALS.charAt(i);\n this.charToByteMap_[this.byteToCharMap_[i]] = i;\n this.byteToCharMapWebSafe_[i] = this.ENCODED_VALS_WEBSAFE.charAt(i);\n this.charToByteMapWebSafe_[this.byteToCharMapWebSafe_[i]] = i;\n\n // Be forgiving when decoding and correctly decode both encodings.\n if (i >= this.ENCODED_VALS_BASE.length) {\n this.charToByteMap_[this.ENCODED_VALS_WEBSAFE.charAt(i)] = i;\n this.charToByteMapWebSafe_[this.ENCODED_VALS.charAt(i)] = i;\n }\n }\n }\n }\n};\n\n/**\n * URL-safe base64 encoding\n */\nexport const base64Encode = function (str: string): string {\n const utf8Bytes = stringToByteArray(str);\n return base64.encodeByteArray(utf8Bytes, true);\n};\n\n/**\n * URL-safe base64 encoding (without \".\" padding in the end).\n * e.g. Used in JSON Web Token (JWT) parts.\n */\nexport const base64urlEncodeWithoutPadding = function (str: string): string {\n // Use base64url encoding and remove padding in the end (dot characters).\n return base64Encode(str).replace(/\\./g, '');\n};\n\n/**\n * URL-safe base64 decoding\n *\n * NOTE: DO NOT use the global atob() function - it does NOT support the\n * base64Url variant encoding.\n *\n * @param str To be decoded\n * @return Decoded result, if possible\n */\nexport const base64Decode = function (str: string): string | null {\n try {\n return base64.decodeString(str, true);\n } catch (e) {\n console.error('base64Decode failed: ', e);\n }\n return null;\n};\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Do a deep-copy of basic JavaScript Objects or Arrays.\n */\nexport function deepCopy(value: T): T {\n return deepExtend(undefined, value) as T;\n}\n\n/**\n * Copy properties from source to target (recursively allows extension\n * of Objects and Arrays). Scalar values in the target are over-written.\n * If target is undefined, an object of the appropriate type will be created\n * (and returned).\n *\n * We recursively copy all child properties of plain Objects in the source- so\n * that namespace- like dictionaries are merged.\n *\n * Note that the target can be a function, in which case the properties in\n * the source Object are copied onto it as static properties of the Function.\n *\n * Note: we don't merge __proto__ to prevent prototype pollution\n */\nexport function deepExtend(target: unknown, source: unknown): unknown {\n if (!(source instanceof Object)) {\n return source;\n }\n\n switch (source.constructor) {\n case Date:\n // Treat Dates like scalars; if the target date object had any child\n // properties - they will be lost!\n const dateValue = source as Date;\n return new Date(dateValue.getTime());\n\n case Object:\n if (target === undefined) {\n target = {};\n }\n break;\n case Array:\n // Always copy the array source and overwrite the target.\n target = [];\n break;\n\n default:\n // Not a plain Object - treat it as a scalar.\n return source;\n }\n\n for (const prop in source) {\n // use isValidKey to guard against prototype pollution. See https://snyk.io/vuln/SNYK-JS-LODASH-450202\n if (!source.hasOwnProperty(prop) || !isValidKey(prop)) {\n continue;\n }\n (target as Record)[prop] = deepExtend(\n (target as Record)[prop],\n (source as Record)[prop]\n );\n }\n\n return target;\n}\n\nfunction isValidKey(key: string): boolean {\n return key !== '__proto__';\n}\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport class Deferred {\n promise: Promise;\n reject: (value?: unknown) => void = () => {};\n resolve: (value?: unknown) => void = () => {};\n constructor() {\n this.promise = new Promise((resolve, reject) => {\n this.resolve = resolve as (value?: unknown) => void;\n this.reject = reject as (value?: unknown) => void;\n });\n }\n\n /**\n * Our API internals are not promiseified and cannot because our callback APIs have subtle expectations around\n * invoking promises inline, which Promises are forbidden to do. This method accepts an optional node-style callback\n * and returns a node-style callback which will resolve or reject the Deferred's promise.\n */\n wrapCallback(\n callback?: (error?: unknown, value?: unknown) => void\n ): (error: unknown, value?: unknown) => void {\n return (error, value?) => {\n if (error) {\n this.reject(error);\n } else {\n this.resolve(value);\n }\n if (typeof callback === 'function') {\n // Attaching noop handler just in case developer wasn't expecting\n // promises\n this.promise.catch(() => {});\n\n // Some of our callbacks don't expect a value and our own tests\n // assert that the parameter length is 1\n if (callback.length === 1) {\n callback(error);\n } else {\n callback(error, value);\n }\n }\n };\n }\n}\n", "/**\n * @license\n * Copyright 2021 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { base64urlEncodeWithoutPadding } from './crypt';\n\n// Firebase Auth tokens contain snake_case claims following the JWT standard / convention.\n/* eslint-disable camelcase */\n\nexport type FirebaseSignInProvider =\n | 'custom'\n | 'email'\n | 'password'\n | 'phone'\n | 'anonymous'\n | 'google.com'\n | 'facebook.com'\n | 'github.com'\n | 'twitter.com'\n | 'microsoft.com'\n | 'apple.com';\n\ninterface FirebaseIdToken {\n // Always set to https://securetoken.google.com/PROJECT_ID\n iss: string;\n\n // Always set to PROJECT_ID\n aud: string;\n\n // The user's unique ID\n sub: string;\n\n // The token issue time, in seconds since epoch\n iat: number;\n\n // The token expiry time, normally 'iat' + 3600\n exp: number;\n\n // The user's unique ID. Must be equal to 'sub'\n user_id: string;\n\n // The time the user authenticated, normally 'iat'\n auth_time: number;\n\n // The sign in provider, only set when the provider is 'anonymous'\n provider_id?: 'anonymous';\n\n // The user's primary email\n email?: string;\n\n // The user's email verification status\n email_verified?: boolean;\n\n // The user's primary phone number\n phone_number?: string;\n\n // The user's display name\n name?: string;\n\n // The user's profile photo URL\n picture?: string;\n\n // Information on all identities linked to this user\n firebase: {\n // The primary sign-in provider\n sign_in_provider: FirebaseSignInProvider;\n\n // A map of providers to the user's list of unique identifiers from\n // each provider\n identities?: { [provider in FirebaseSignInProvider]?: string[] };\n };\n\n // Custom claims set by the developer\n [claim: string]: unknown;\n\n uid?: never; // Try to catch a common mistake of \"uid\" (should be \"sub\" instead).\n}\n\nexport type EmulatorMockTokenOptions = ({ user_id: string } | { sub: string }) &\n Partial;\n\nexport function createMockUserToken(\n token: EmulatorMockTokenOptions,\n projectId?: string\n): string {\n if (token.uid) {\n throw new Error(\n 'The \"uid\" field is no longer supported by mockUserToken. Please use \"sub\" instead for Firebase Auth User ID.'\n );\n }\n // Unsecured JWTs use \"none\" as the algorithm.\n const header = {\n alg: 'none',\n type: 'JWT'\n };\n\n const project = projectId || 'demo-project';\n const iat = token.iat || 0;\n const sub = token.sub || token.user_id;\n if (!sub) {\n throw new Error(\"mockUserToken must contain 'sub' or 'user_id' field!\");\n }\n\n const payload: FirebaseIdToken = {\n // Set all required fields to decent defaults\n iss: `https://securetoken.google.com/${project}`,\n aud: project,\n iat,\n exp: iat + 3600,\n auth_time: iat,\n sub,\n user_id: sub,\n firebase: {\n sign_in_provider: 'custom',\n identities: {}\n },\n\n // Override with user options\n ...token\n };\n\n // Unsecured JWTs use the empty string as a signature.\n const signature = '';\n return [\n base64urlEncodeWithoutPadding(JSON.stringify(header)),\n base64urlEncodeWithoutPadding(JSON.stringify(payload)),\n signature\n ].join('.');\n}\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { CONSTANTS } from './constants';\n\n/**\n * Returns navigator.userAgent string or '' if it's not defined.\n * @return user agent string\n */\nexport function getUA(): string {\n if (\n typeof navigator !== 'undefined' &&\n typeof navigator['userAgent'] === 'string'\n ) {\n return navigator['userAgent'];\n } else {\n return '';\n }\n}\n\n/**\n * Detect Cordova / PhoneGap / Ionic frameworks on a mobile device.\n *\n * Deliberately does not rely on checking `file://` URLs (as this fails PhoneGap\n * in the Ripple emulator) nor Cordova `onDeviceReady`, which would normally\n * wait for a callback.\n */\nexport function isMobileCordova(): boolean {\n return (\n typeof window !== 'undefined' &&\n // @ts-ignore Setting up an broadly applicable index signature for Window\n // just to deal with this case would probably be a bad idea.\n !!(window['cordova'] || window['phonegap'] || window['PhoneGap']) &&\n /ios|iphone|ipod|ipad|android|blackberry|iemobile/i.test(getUA())\n );\n}\n\n/**\n * Detect Node.js.\n *\n * @return true if Node.js environment is detected.\n */\n// Node detection logic from: https://github.com/iliakan/detect-node/\nexport function isNode(): boolean {\n try {\n return (\n Object.prototype.toString.call(global.process) === '[object process]'\n );\n } catch (e) {\n return false;\n }\n}\n\n/**\n * Detect Browser Environment\n */\nexport function isBrowser(): boolean {\n return typeof self === 'object' && self.self === self;\n}\n\n/**\n * Detect browser extensions (Chrome and Firefox at least).\n */\ninterface BrowserRuntime {\n id?: unknown;\n}\ndeclare const chrome: { runtime?: BrowserRuntime };\ndeclare const browser: { runtime?: BrowserRuntime };\nexport function isBrowserExtension(): boolean {\n const runtime =\n typeof chrome === 'object'\n ? chrome.runtime\n : typeof browser === 'object'\n ? browser.runtime\n : undefined;\n return typeof runtime === 'object' && runtime.id !== undefined;\n}\n\n/**\n * Detect React Native.\n *\n * @return true if ReactNative environment is detected.\n */\nexport function isReactNative(): boolean {\n return (\n typeof navigator === 'object' && navigator['product'] === 'ReactNative'\n );\n}\n\n/** Detects Electron apps. */\nexport function isElectron(): boolean {\n return getUA().indexOf('Electron/') >= 0;\n}\n\n/** Detects Internet Explorer. */\nexport function isIE(): boolean {\n const ua = getUA();\n return ua.indexOf('MSIE ') >= 0 || ua.indexOf('Trident/') >= 0;\n}\n\n/** Detects Universal Windows Platform apps. */\nexport function isUWP(): boolean {\n return getUA().indexOf('MSAppHost/') >= 0;\n}\n\n/**\n * Detect whether the current SDK build is the Node version.\n *\n * @return true if it's the Node SDK build.\n */\nexport function isNodeSdk(): boolean {\n return CONSTANTS.NODE_CLIENT === true || CONSTANTS.NODE_ADMIN === true;\n}\n\n/** Returns true if we are running in Safari. */\nexport function isSafari(): boolean {\n return (\n !isNode() &&\n navigator.userAgent.includes('Safari') &&\n !navigator.userAgent.includes('Chrome')\n );\n}\n\n/**\n * This method checks if indexedDB is supported by current browser/service worker context\n * @return true if indexedDB is supported by current browser/service worker context\n */\nexport function isIndexedDBAvailable(): boolean {\n return typeof indexedDB === 'object';\n}\n\n/**\n * This method validates browser/sw context for indexedDB by opening a dummy indexedDB database and reject\n * if errors occur during the database open operation.\n *\n * @throws exception if current browser/sw context can't run idb.open (ex: Safari iframe, Firefox\n * private browsing)\n */\nexport function validateIndexedDBOpenable(): Promise {\n return new Promise((resolve, reject) => {\n try {\n let preExist: boolean = true;\n const DB_CHECK_NAME =\n 'validate-browser-context-for-indexeddb-analytics-module';\n const request = self.indexedDB.open(DB_CHECK_NAME);\n request.onsuccess = () => {\n request.result.close();\n // delete database only when it doesn't pre-exist\n if (!preExist) {\n self.indexedDB.deleteDatabase(DB_CHECK_NAME);\n }\n resolve(true);\n };\n request.onupgradeneeded = () => {\n preExist = false;\n };\n\n request.onerror = () => {\n reject(request.error?.message || '');\n };\n } catch (error) {\n reject(error);\n }\n });\n}\n\n/**\n *\n * This method checks whether cookie is enabled within current browser\n * @return true if cookie is enabled within current browser\n */\nexport function areCookiesEnabled(): boolean {\n if (typeof navigator === 'undefined' || !navigator.cookieEnabled) {\n return false;\n }\n return true;\n}\n\n/**\n * Polyfill for `globalThis` object.\n * @returns the `globalThis` object for the given environment.\n */\nexport function getGlobal(): typeof globalThis {\n if (typeof self !== 'undefined') {\n return self;\n }\n if (typeof window !== 'undefined') {\n return window;\n }\n if (typeof global !== 'undefined') {\n return global;\n }\n throw new Error('Unable to locate global object.');\n}\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/**\n * @fileoverview Standardized Firebase Error.\n *\n * Usage:\n *\n * // Typescript string literals for type-safe codes\n * type Err =\n * 'unknown' |\n * 'object-not-found'\n * ;\n *\n * // Closure enum for type-safe error codes\n * // at-enum {string}\n * var Err = {\n * UNKNOWN: 'unknown',\n * OBJECT_NOT_FOUND: 'object-not-found',\n * }\n *\n * let errors: Map = {\n * 'generic-error': \"Unknown error\",\n * 'file-not-found': \"Could not find file: {$file}\",\n * };\n *\n * // Type-safe function - must pass a valid error code as param.\n * let error = new ErrorFactory('service', 'Service', errors);\n *\n * ...\n * throw error.create(Err.GENERIC);\n * ...\n * throw error.create(Err.FILE_NOT_FOUND, {'file': fileName});\n * ...\n * // Service: Could not file file: foo.txt (service/file-not-found).\n *\n * catch (e) {\n * assert(e.message === \"Could not find file: foo.txt.\");\n * if ((e as FirebaseError)?.code === 'service/file-not-found') {\n * console.log(\"Could not read file: \" + e['file']);\n * }\n * }\n */\n\nexport type ErrorMap = {\n readonly [K in ErrorCode]: string;\n};\n\nconst ERROR_NAME = 'FirebaseError';\n\nexport interface StringLike {\n toString(): string;\n}\n\nexport interface ErrorData {\n [key: string]: unknown;\n}\n\n// Based on code from:\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error#Custom_Error_Types\nexport class FirebaseError extends Error {\n /** The custom name for all FirebaseErrors. */\n readonly name: string = ERROR_NAME;\n\n constructor(\n /** The error code for this error. */\n readonly code: string,\n message: string,\n /** Custom data for this error. */\n public customData?: Record\n ) {\n super(message);\n\n // Fix For ES5\n // https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work\n Object.setPrototypeOf(this, FirebaseError.prototype);\n\n // Maintains proper stack trace for where our error was thrown.\n // Only available on V8.\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, ErrorFactory.prototype.create);\n }\n }\n}\n\nexport class ErrorFactory<\n ErrorCode extends string,\n ErrorParams extends { readonly [K in ErrorCode]?: ErrorData } = {}\n> {\n constructor(\n private readonly service: string,\n private readonly serviceName: string,\n private readonly errors: ErrorMap\n ) {}\n\n create(\n code: K,\n ...data: K extends keyof ErrorParams ? [ErrorParams[K]] : []\n ): FirebaseError {\n const customData = (data[0] as ErrorData) || {};\n const fullCode = `${this.service}/${code}`;\n const template = this.errors[code];\n\n const message = template ? replaceTemplate(template, customData) : 'Error';\n // Service Name: Error message (service/code).\n const fullMessage = `${this.serviceName}: ${message} (${fullCode}).`;\n\n const error = new FirebaseError(fullCode, fullMessage, customData);\n\n return error;\n }\n}\n\nfunction replaceTemplate(template: string, data: ErrorData): string {\n return template.replace(PATTERN, (_, key) => {\n const value = data[key];\n return value != null ? String(value) : `<${key}?>`;\n });\n}\n\nconst PATTERN = /\\{\\$([^}]+)}/g;\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Evaluates a JSON string into a javascript object.\n *\n * @param {string} str A string containing JSON.\n * @return {*} The javascript object representing the specified JSON.\n */\nexport function jsonEval(str: string): unknown {\n return JSON.parse(str);\n}\n\n/**\n * Returns JSON representing a javascript object.\n * @param {*} data Javascript object to be stringified.\n * @return {string} The JSON contents of the object.\n */\nexport function stringify(data: unknown): string {\n return JSON.stringify(data);\n}\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { base64Decode } from './crypt';\nimport { jsonEval } from './json';\n\ninterface Claims {\n [key: string]: {};\n}\n\ninterface DecodedToken {\n header: object;\n claims: Claims;\n data: object;\n signature: string;\n}\n\n/**\n * Decodes a Firebase auth. token into constituent parts.\n *\n * Notes:\n * - May return with invalid / incomplete claims if there's no native base64 decoding support.\n * - Doesn't check if the token is actually valid.\n */\nexport const decode = function (token: string): DecodedToken {\n let header = {},\n claims: Claims = {},\n data = {},\n signature = '';\n\n try {\n const parts = token.split('.');\n header = jsonEval(base64Decode(parts[0]) || '') as object;\n claims = jsonEval(base64Decode(parts[1]) || '') as Claims;\n signature = parts[2];\n data = claims['d'] || {};\n delete claims['d'];\n } catch (e) {}\n\n return {\n header,\n claims,\n data,\n signature\n };\n};\n\ninterface DecodedToken {\n header: object;\n claims: Claims;\n data: object;\n signature: string;\n}\n\n/**\n * Decodes a Firebase auth. token and checks the validity of its time-based claims. Will return true if the\n * token is within the time window authorized by the 'nbf' (not-before) and 'iat' (issued-at) claims.\n *\n * Notes:\n * - May return a false negative if there's no native base64 decoding support.\n * - Doesn't check if the token is actually valid.\n */\nexport const isValidTimestamp = function (token: string): boolean {\n const claims: Claims = decode(token).claims;\n const now: number = Math.floor(new Date().getTime() / 1000);\n let validSince: number = 0,\n validUntil: number = 0;\n\n if (typeof claims === 'object') {\n if (claims.hasOwnProperty('nbf')) {\n validSince = claims['nbf'] as number;\n } else if (claims.hasOwnProperty('iat')) {\n validSince = claims['iat'] as number;\n }\n\n if (claims.hasOwnProperty('exp')) {\n validUntil = claims['exp'] as number;\n } else {\n // token will expire after 24h by default\n validUntil = validSince + 86400;\n }\n }\n\n return (\n !!now &&\n !!validSince &&\n !!validUntil &&\n now >= validSince &&\n now <= validUntil\n );\n};\n\n/**\n * Decodes a Firebase auth. token and returns its issued at time if valid, null otherwise.\n *\n * Notes:\n * - May return null if there's no native base64 decoding support.\n * - Doesn't check if the token is actually valid.\n */\nexport const issuedAtTime = function (token: string): number | null {\n const claims: Claims = decode(token).claims;\n if (typeof claims === 'object' && claims.hasOwnProperty('iat')) {\n return claims['iat'] as number;\n }\n return null;\n};\n\n/**\n * Decodes a Firebase auth. token and checks the validity of its format. Expects a valid issued-at time.\n *\n * Notes:\n * - May return a false negative if there's no native base64 decoding support.\n * - Doesn't check if the token is actually valid.\n */\nexport const isValidFormat = function (token: string): boolean {\n const decoded = decode(token),\n claims = decoded.claims;\n\n return !!claims && typeof claims === 'object' && claims.hasOwnProperty('iat');\n};\n\n/**\n * Attempts to peer into an auth token and determine if it's an admin auth token by looking at the claims portion.\n *\n * Notes:\n * - May return a false negative if there's no native base64 decoding support.\n * - Doesn't check if the token is actually valid.\n */\nexport const isAdmin = function (token: string): boolean {\n const claims: Claims = decode(token).claims;\n return typeof claims === 'object' && claims['admin'] === true;\n};\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport function contains(obj: T, key: string): boolean {\n return Object.prototype.hasOwnProperty.call(obj, key);\n}\n\nexport function safeGet(\n obj: T,\n key: K\n): T[K] | undefined {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n return obj[key];\n } else {\n return undefined;\n }\n}\n\nexport function isEmpty(obj: object): obj is {} {\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n return false;\n }\n }\n return true;\n}\n\nexport function map(\n obj: { [key in K]: V },\n fn: (value: V, key: K, obj: { [key in K]: V }) => U,\n contextObj?: unknown\n): { [key in K]: U } {\n const res: Partial<{ [key in K]: U }> = {};\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n res[key] = fn.call(contextObj, obj[key], key, obj);\n }\n }\n return res as { [key in K]: U };\n}\n\n/**\n * Deep equal two objects. Support Arrays and Objects.\n */\nexport function deepEqual(a: object, b: object): boolean {\n if (a === b) {\n return true;\n }\n\n const aKeys = Object.keys(a);\n const bKeys = Object.keys(b);\n for (const k of aKeys) {\n if (!bKeys.includes(k)) {\n return false;\n }\n\n const aProp = (a as Record)[k];\n const bProp = (b as Record)[k];\n if (isObject(aProp) && isObject(bProp)) {\n if (!deepEqual(aProp, bProp)) {\n return false;\n }\n } else if (aProp !== bProp) {\n return false;\n }\n }\n\n for (const k of bKeys) {\n if (!aKeys.includes(k)) {\n return false;\n }\n }\n return true;\n}\n\nfunction isObject(thing: unknown): thing is object {\n return thing !== null && typeof thing === 'object';\n}\n", "/**\n * @license\n * Copyright 2022 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Deferred } from './deferred';\n\n/**\n * Rejects if the given promise doesn't resolve in timeInMS milliseconds.\n * @internal\n */\nexport function promiseWithTimeout(\n promise: Promise,\n timeInMS = 2000\n): Promise {\n const deferredPromise = new Deferred();\n setTimeout(() => deferredPromise.reject('timeout!'), timeInMS);\n promise.then(deferredPromise.resolve, deferredPromise.reject);\n return deferredPromise.promise;\n}\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Returns a querystring-formatted string (e.g. &arg=val&arg2=val2) from a\n * params object (e.g. {arg: 'val', arg2: 'val2'})\n * Note: You must prepend it with ? when adding it to a URL.\n */\nexport function querystring(querystringParams: {\n [key: string]: string | number;\n}): string {\n const params = [];\n for (const [key, value] of Object.entries(querystringParams)) {\n if (Array.isArray(value)) {\n value.forEach(arrayVal => {\n params.push(\n encodeURIComponent(key) + '=' + encodeURIComponent(arrayVal)\n );\n });\n } else {\n params.push(encodeURIComponent(key) + '=' + encodeURIComponent(value));\n }\n }\n return params.length ? '&' + params.join('&') : '';\n}\n\n/**\n * Decodes a querystring (e.g. ?arg=val&arg2=val2) into a params object\n * (e.g. {arg: 'val', arg2: 'val2'})\n */\nexport function querystringDecode(querystring: string): Record {\n const obj: Record = {};\n const tokens = querystring.replace(/^\\?/, '').split('&');\n\n tokens.forEach(token => {\n if (token) {\n const [key, value] = token.split('=');\n obj[decodeURIComponent(key)] = decodeURIComponent(value);\n }\n });\n return obj;\n}\n\n/**\n * Extract the query string part of a URL, including the leading question mark (if present).\n */\nexport function extractQuerystring(url: string): string {\n const queryStart = url.indexOf('?');\n if (!queryStart) {\n return '';\n }\n const fragmentStart = url.indexOf('#', queryStart);\n return url.substring(\n queryStart,\n fragmentStart > 0 ? fragmentStart : undefined\n );\n}\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * @fileoverview SHA-1 cryptographic hash.\n * Variable names follow the notation in FIPS PUB 180-3:\n * http://csrc.nist.gov/publications/fips/fips180-3/fips180-3_final.pdf.\n *\n * Usage:\n * var sha1 = new sha1();\n * sha1.update(bytes);\n * var hash = sha1.digest();\n *\n * Performance:\n * Chrome 23: ~400 Mbit/s\n * Firefox 16: ~250 Mbit/s\n *\n */\n\n/**\n * SHA-1 cryptographic hash constructor.\n *\n * The properties declared here are discussed in the above algorithm document.\n * @constructor\n * @final\n * @struct\n */\nexport class Sha1 {\n /**\n * Holds the previous values of accumulated variables a-e in the compress_\n * function.\n * @private\n */\n private chain_: number[] = [];\n\n /**\n * A buffer holding the partially computed hash result.\n * @private\n */\n private buf_: number[] = [];\n\n /**\n * An array of 80 bytes, each a part of the message to be hashed. Referred to\n * as the message schedule in the docs.\n * @private\n */\n private W_: number[] = [];\n\n /**\n * Contains data needed to pad messages less than 64 bytes.\n * @private\n */\n private pad_: number[] = [];\n\n /**\n * @private {number}\n */\n private inbuf_: number = 0;\n\n /**\n * @private {number}\n */\n private total_: number = 0;\n\n blockSize: number;\n\n constructor() {\n this.blockSize = 512 / 8;\n\n this.pad_[0] = 128;\n for (let i = 1; i < this.blockSize; ++i) {\n this.pad_[i] = 0;\n }\n\n this.reset();\n }\n\n reset(): void {\n this.chain_[0] = 0x67452301;\n this.chain_[1] = 0xefcdab89;\n this.chain_[2] = 0x98badcfe;\n this.chain_[3] = 0x10325476;\n this.chain_[4] = 0xc3d2e1f0;\n\n this.inbuf_ = 0;\n this.total_ = 0;\n }\n\n /**\n * Internal compress helper function.\n * @param buf Block to compress.\n * @param offset Offset of the block in the buffer.\n * @private\n */\n compress_(buf: number[] | Uint8Array | string, offset?: number): void {\n if (!offset) {\n offset = 0;\n }\n\n const W = this.W_;\n\n // get 16 big endian words\n if (typeof buf === 'string') {\n for (let i = 0; i < 16; i++) {\n // TODO(user): [bug 8140122] Recent versions of Safari for Mac OS and iOS\n // have a bug that turns the post-increment ++ operator into pre-increment\n // during JIT compilation. We have code that depends heavily on SHA-1 for\n // correctness and which is affected by this bug, so I've removed all uses\n // of post-increment ++ in which the result value is used. We can revert\n // this change once the Safari bug\n // (https://bugs.webkit.org/show_bug.cgi?id=109036) has been fixed and\n // most clients have been updated.\n W[i] =\n (buf.charCodeAt(offset) << 24) |\n (buf.charCodeAt(offset + 1) << 16) |\n (buf.charCodeAt(offset + 2) << 8) |\n buf.charCodeAt(offset + 3);\n offset += 4;\n }\n } else {\n for (let i = 0; i < 16; i++) {\n W[i] =\n (buf[offset] << 24) |\n (buf[offset + 1] << 16) |\n (buf[offset + 2] << 8) |\n buf[offset + 3];\n offset += 4;\n }\n }\n\n // expand to 80 words\n for (let i = 16; i < 80; i++) {\n const t = W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16];\n W[i] = ((t << 1) | (t >>> 31)) & 0xffffffff;\n }\n\n let a = this.chain_[0];\n let b = this.chain_[1];\n let c = this.chain_[2];\n let d = this.chain_[3];\n let e = this.chain_[4];\n let f, k;\n\n // TODO(user): Try to unroll this loop to speed up the computation.\n for (let i = 0; i < 80; i++) {\n if (i < 40) {\n if (i < 20) {\n f = d ^ (b & (c ^ d));\n k = 0x5a827999;\n } else {\n f = b ^ c ^ d;\n k = 0x6ed9eba1;\n }\n } else {\n if (i < 60) {\n f = (b & c) | (d & (b | c));\n k = 0x8f1bbcdc;\n } else {\n f = b ^ c ^ d;\n k = 0xca62c1d6;\n }\n }\n\n const t = (((a << 5) | (a >>> 27)) + f + e + k + W[i]) & 0xffffffff;\n e = d;\n d = c;\n c = ((b << 30) | (b >>> 2)) & 0xffffffff;\n b = a;\n a = t;\n }\n\n this.chain_[0] = (this.chain_[0] + a) & 0xffffffff;\n this.chain_[1] = (this.chain_[1] + b) & 0xffffffff;\n this.chain_[2] = (this.chain_[2] + c) & 0xffffffff;\n this.chain_[3] = (this.chain_[3] + d) & 0xffffffff;\n this.chain_[4] = (this.chain_[4] + e) & 0xffffffff;\n }\n\n update(bytes?: number[] | Uint8Array | string, length?: number): void {\n // TODO(johnlenz): tighten the function signature and remove this check\n if (bytes == null) {\n return;\n }\n\n if (length === undefined) {\n length = bytes.length;\n }\n\n const lengthMinusBlock = length - this.blockSize;\n let n = 0;\n // Using local instead of member variables gives ~5% speedup on Firefox 16.\n const buf = this.buf_;\n let inbuf = this.inbuf_;\n\n // The outer while loop should execute at most twice.\n while (n < length) {\n // When we have no data in the block to top up, we can directly process the\n // input buffer (assuming it contains sufficient data). This gives ~25%\n // speedup on Chrome 23 and ~15% speedup on Firefox 16, but requires that\n // the data is provided in large chunks (or in multiples of 64 bytes).\n if (inbuf === 0) {\n while (n <= lengthMinusBlock) {\n this.compress_(bytes, n);\n n += this.blockSize;\n }\n }\n\n if (typeof bytes === 'string') {\n while (n < length) {\n buf[inbuf] = bytes.charCodeAt(n);\n ++inbuf;\n ++n;\n if (inbuf === this.blockSize) {\n this.compress_(buf);\n inbuf = 0;\n // Jump to the outer loop so we use the full-block optimization.\n break;\n }\n }\n } else {\n while (n < length) {\n buf[inbuf] = bytes[n];\n ++inbuf;\n ++n;\n if (inbuf === this.blockSize) {\n this.compress_(buf);\n inbuf = 0;\n // Jump to the outer loop so we use the full-block optimization.\n break;\n }\n }\n }\n }\n\n this.inbuf_ = inbuf;\n this.total_ += length;\n }\n\n /** @override */\n digest(): number[] {\n const digest: number[] = [];\n let totalBits = this.total_ * 8;\n\n // Add pad 0x80 0x00*.\n if (this.inbuf_ < 56) {\n this.update(this.pad_, 56 - this.inbuf_);\n } else {\n this.update(this.pad_, this.blockSize - (this.inbuf_ - 56));\n }\n\n // Add # bits.\n for (let i = this.blockSize - 1; i >= 56; i--) {\n this.buf_[i] = totalBits & 255;\n totalBits /= 256; // Don't use bit-shifting here!\n }\n\n this.compress_(this.buf_);\n\n let n = 0;\n for (let i = 0; i < 5; i++) {\n for (let j = 24; j >= 0; j -= 8) {\n digest[n] = (this.chain_[i] >> j) & 255;\n ++n;\n }\n }\n return digest;\n }\n}\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nexport type NextFn = (value: T) => void;\nexport type ErrorFn = (error: Error) => void;\nexport type CompleteFn = () => void;\n\nexport interface Observer {\n // Called once for each value in a stream of values.\n next: NextFn;\n\n // A stream terminates by a single call to EITHER error() or complete().\n error: ErrorFn;\n\n // No events will be sent to next() once complete() is called.\n complete: CompleteFn;\n}\n\nexport type PartialObserver = Partial>;\n\n// TODO: Support also Unsubscribe.unsubscribe?\nexport type Unsubscribe = () => void;\n\n/**\n * The Subscribe interface has two forms - passing the inline function\n * callbacks, or a object interface with callback properties.\n */\nexport interface Subscribe {\n (next?: NextFn, error?: ErrorFn, complete?: CompleteFn): Unsubscribe;\n (observer: PartialObserver): Unsubscribe;\n}\n\nexport interface Observable {\n // Subscribe method\n subscribe: Subscribe;\n}\n\nexport type Executor = (observer: Observer) => void;\n\n/**\n * Helper to make a Subscribe function (just like Promise helps make a\n * Thenable).\n *\n * @param executor Function which can make calls to a single Observer\n * as a proxy.\n * @param onNoObservers Callback when count of Observers goes to zero.\n */\nexport function createSubscribe(\n executor: Executor,\n onNoObservers?: Executor\n): Subscribe {\n const proxy = new ObserverProxy(executor, onNoObservers);\n return proxy.subscribe.bind(proxy);\n}\n\n/**\n * Implement fan-out for any number of Observers attached via a subscribe\n * function.\n */\nclass ObserverProxy implements Observer {\n private observers: Array> | undefined = [];\n private unsubscribes: Unsubscribe[] = [];\n private onNoObservers: Executor | undefined;\n private observerCount = 0;\n // Micro-task scheduling by calling task.then().\n private task = Promise.resolve();\n private finalized = false;\n private finalError?: Error;\n\n /**\n * @param executor Function which can make calls to a single Observer\n * as a proxy.\n * @param onNoObservers Callback when count of Observers goes to zero.\n */\n constructor(executor: Executor, onNoObservers?: Executor) {\n this.onNoObservers = onNoObservers;\n // Call the executor asynchronously so subscribers that are called\n // synchronously after the creation of the subscribe function\n // can still receive the very first value generated in the executor.\n this.task\n .then(() => {\n executor(this);\n })\n .catch(e => {\n this.error(e);\n });\n }\n\n next(value: T): void {\n this.forEachObserver((observer: Observer) => {\n observer.next(value);\n });\n }\n\n error(error: Error): void {\n this.forEachObserver((observer: Observer) => {\n observer.error(error);\n });\n this.close(error);\n }\n\n complete(): void {\n this.forEachObserver((observer: Observer) => {\n observer.complete();\n });\n this.close();\n }\n\n /**\n * Subscribe function that can be used to add an Observer to the fan-out list.\n *\n * - We require that no event is sent to a subscriber sychronously to their\n * call to subscribe().\n */\n subscribe(\n nextOrObserver?: NextFn | PartialObserver,\n error?: ErrorFn,\n complete?: CompleteFn\n ): Unsubscribe {\n let observer: Observer;\n\n if (\n nextOrObserver === undefined &&\n error === undefined &&\n complete === undefined\n ) {\n throw new Error('Missing Observer.');\n }\n\n // Assemble an Observer object when passed as callback functions.\n if (\n implementsAnyMethods(nextOrObserver as { [key: string]: unknown }, [\n 'next',\n 'error',\n 'complete'\n ])\n ) {\n observer = nextOrObserver as Observer;\n } else {\n observer = {\n next: nextOrObserver as NextFn,\n error,\n complete\n } as Observer;\n }\n\n if (observer.next === undefined) {\n observer.next = noop as NextFn;\n }\n if (observer.error === undefined) {\n observer.error = noop as ErrorFn;\n }\n if (observer.complete === undefined) {\n observer.complete = noop as CompleteFn;\n }\n\n const unsub = this.unsubscribeOne.bind(this, this.observers!.length);\n\n // Attempt to subscribe to a terminated Observable - we\n // just respond to the Observer with the final error or complete\n // event.\n if (this.finalized) {\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.task.then(() => {\n try {\n if (this.finalError) {\n observer.error(this.finalError);\n } else {\n observer.complete();\n }\n } catch (e) {\n // nothing\n }\n return;\n });\n }\n\n this.observers!.push(observer as Observer);\n\n return unsub;\n }\n\n // Unsubscribe is synchronous - we guarantee that no events are sent to\n // any unsubscribed Observer.\n private unsubscribeOne(i: number): void {\n if (this.observers === undefined || this.observers[i] === undefined) {\n return;\n }\n\n delete this.observers[i];\n\n this.observerCount -= 1;\n if (this.observerCount === 0 && this.onNoObservers !== undefined) {\n this.onNoObservers(this);\n }\n }\n\n private forEachObserver(fn: (observer: Observer) => void): void {\n if (this.finalized) {\n // Already closed by previous event....just eat the additional values.\n return;\n }\n\n // Since sendOne calls asynchronously - there is no chance that\n // this.observers will become undefined.\n for (let i = 0; i < this.observers!.length; i++) {\n this.sendOne(i, fn);\n }\n }\n\n // Call the Observer via one of it's callback function. We are careful to\n // confirm that the observe has not been unsubscribed since this asynchronous\n // function had been queued.\n private sendOne(i: number, fn: (observer: Observer) => void): void {\n // Execute the callback asynchronously\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.task.then(() => {\n if (this.observers !== undefined && this.observers[i] !== undefined) {\n try {\n fn(this.observers[i]);\n } catch (e) {\n // Ignore exceptions raised in Observers or missing methods of an\n // Observer.\n // Log error to console. b/31404806\n if (typeof console !== 'undefined' && console.error) {\n console.error(e);\n }\n }\n }\n });\n }\n\n private close(err?: Error): void {\n if (this.finalized) {\n return;\n }\n this.finalized = true;\n if (err !== undefined) {\n this.finalError = err;\n }\n // Proxy is no longer needed - garbage collect references\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.task.then(() => {\n this.observers = undefined;\n this.onNoObservers = undefined;\n });\n }\n}\n\n/** Turn synchronous function into one called asynchronously. */\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport function async(fn: Function, onError?: ErrorFn): Function {\n return (...args: unknown[]) => {\n Promise.resolve(true)\n .then(() => {\n fn(...args);\n })\n .catch((error: Error) => {\n if (onError) {\n onError(error);\n }\n });\n };\n}\n\n/**\n * Return true if the object passed in implements any of the named methods.\n */\nfunction implementsAnyMethods(\n obj: { [key: string]: unknown },\n methods: string[]\n): boolean {\n if (typeof obj !== 'object' || obj === null) {\n return false;\n }\n\n for (const method of methods) {\n if (method in obj && typeof obj[method] === 'function') {\n return true;\n }\n }\n\n return false;\n}\n\nfunction noop(): void {\n // do nothing\n}\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Check to make sure the appropriate number of arguments are provided for a public function.\n * Throws an error if it fails.\n *\n * @param fnName The function name\n * @param minCount The minimum number of arguments to allow for the function call\n * @param maxCount The maximum number of argument to allow for the function call\n * @param argCount The actual number of arguments provided.\n */\nexport const validateArgCount = function (\n fnName: string,\n minCount: number,\n maxCount: number,\n argCount: number\n): void {\n let argError;\n if (argCount < minCount) {\n argError = 'at least ' + minCount;\n } else if (argCount > maxCount) {\n argError = maxCount === 0 ? 'none' : 'no more than ' + maxCount;\n }\n if (argError) {\n const error =\n fnName +\n ' failed: Was called with ' +\n argCount +\n (argCount === 1 ? ' argument.' : ' arguments.') +\n ' Expects ' +\n argError +\n '.';\n throw new Error(error);\n }\n};\n\n/**\n * Generates a string to prefix an error message about failed argument validation\n *\n * @param fnName The function name\n * @param argName The name of the argument\n * @return The prefix to add to the error thrown for validation.\n */\nexport function errorPrefix(fnName: string, argName: string): string {\n return `${fnName} failed: ${argName} argument `;\n}\n\n/**\n * @param fnName\n * @param argumentNumber\n * @param namespace\n * @param optional\n */\nexport function validateNamespace(\n fnName: string,\n namespace: string,\n optional: boolean\n): void {\n if (optional && !namespace) {\n return;\n }\n if (typeof namespace !== 'string') {\n //TODO: I should do more validation here. We only allow certain chars in namespaces.\n throw new Error(\n errorPrefix(fnName, 'namespace') + 'must be a valid firebase namespace.'\n );\n }\n}\n\nexport function validateCallback(\n fnName: string,\n argumentName: string,\n // eslint-disable-next-line @typescript-eslint/ban-types\n callback: Function,\n optional: boolean\n): void {\n if (optional && !callback) {\n return;\n }\n if (typeof callback !== 'function') {\n throw new Error(\n errorPrefix(fnName, argumentName) + 'must be a valid function.'\n );\n }\n}\n\nexport function validateContextObject(\n fnName: string,\n argumentName: string,\n context: unknown,\n optional: boolean\n): void {\n if (optional && !context) {\n return;\n }\n if (typeof context !== 'object' || context === null) {\n throw new Error(\n errorPrefix(fnName, argumentName) + 'must be a valid context object.'\n );\n }\n}\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { assert } from './assert';\n\n// Code originally came from goog.crypt.stringToUtf8ByteArray, but for some reason they\n// automatically replaced '\\r\\n' with '\\n', and they didn't handle surrogate pairs,\n// so it's been modified.\n\n// Note that not all Unicode characters appear as single characters in JavaScript strings.\n// fromCharCode returns the UTF-16 encoding of a character - so some Unicode characters\n// use 2 characters in Javascript. All 4-byte UTF-8 characters begin with a first\n// character in the range 0xD800 - 0xDBFF (the first character of a so-called surrogate\n// pair).\n// See http://www.ecma-international.org/ecma-262/5.1/#sec-15.1.3\n\n/**\n * @param {string} str\n * @return {Array}\n */\nexport const stringToByteArray = function (str: string): number[] {\n const out: number[] = [];\n let p = 0;\n for (let i = 0; i < str.length; i++) {\n let c = str.charCodeAt(i);\n\n // Is this the lead surrogate in a surrogate pair?\n if (c >= 0xd800 && c <= 0xdbff) {\n const high = c - 0xd800; // the high 10 bits.\n i++;\n assert(i < str.length, 'Surrogate pair missing trail surrogate.');\n const low = str.charCodeAt(i) - 0xdc00; // the low 10 bits.\n c = 0x10000 + (high << 10) + low;\n }\n\n if (c < 128) {\n out[p++] = c;\n } else if (c < 2048) {\n out[p++] = (c >> 6) | 192;\n out[p++] = (c & 63) | 128;\n } else if (c < 65536) {\n out[p++] = (c >> 12) | 224;\n out[p++] = ((c >> 6) & 63) | 128;\n out[p++] = (c & 63) | 128;\n } else {\n out[p++] = (c >> 18) | 240;\n out[p++] = ((c >> 12) & 63) | 128;\n out[p++] = ((c >> 6) & 63) | 128;\n out[p++] = (c & 63) | 128;\n }\n }\n return out;\n};\n\n/**\n * Calculate length without actually converting; useful for doing cheaper validation.\n * @param {string} str\n * @return {number}\n */\nexport const stringLength = function (str: string): number {\n let p = 0;\n for (let i = 0; i < str.length; i++) {\n const c = str.charCodeAt(i);\n if (c < 128) {\n p++;\n } else if (c < 2048) {\n p += 2;\n } else if (c >= 0xd800 && c <= 0xdbff) {\n // Lead surrogate of a surrogate pair. The pair together will take 4 bytes to represent.\n p += 4;\n i++; // skip trail surrogate.\n } else {\n p += 3;\n }\n }\n return p;\n};\n", "/**\n * @license\n * Copyright 2022 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Copied from https://stackoverflow.com/a/2117523\n * Generates a new uuid.\n * @public\n */\nexport const uuidv4 = function (): string {\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {\n const r = (Math.random() * 16) | 0,\n v = c === 'x' ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n};\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * The amount of milliseconds to exponentially increase.\n */\nconst DEFAULT_INTERVAL_MILLIS = 1000;\n\n/**\n * The factor to backoff by.\n * Should be a number greater than 1.\n */\nconst DEFAULT_BACKOFF_FACTOR = 2;\n\n/**\n * The maximum milliseconds to increase to.\n *\n *

Visible for testing\n */\nexport const MAX_VALUE_MILLIS = 4 * 60 * 60 * 1000; // Four hours, like iOS and Android.\n\n/**\n * The percentage of backoff time to randomize by.\n * See\n * http://go/safe-client-behavior#step-1-determine-the-appropriate-retry-interval-to-handle-spike-traffic\n * for context.\n *\n *

Visible for testing\n */\nexport const RANDOM_FACTOR = 0.5;\n\n/**\n * Based on the backoff method from\n * https://github.com/google/closure-library/blob/master/closure/goog/math/exponentialbackoff.js.\n * Extracted here so we don't need to pass metadata and a stateful ExponentialBackoff object around.\n */\nexport function calculateBackoffMillis(\n backoffCount: number,\n intervalMillis: number = DEFAULT_INTERVAL_MILLIS,\n backoffFactor: number = DEFAULT_BACKOFF_FACTOR\n): number {\n // Calculates an exponentially increasing value.\n // Deviation: calculates value from count and a constant interval, so we only need to save value\n // and count to restore state.\n const currBaseValue = intervalMillis * Math.pow(backoffFactor, backoffCount);\n\n // A random \"fuzz\" to avoid waves of retries.\n // Deviation: randomFactor is required.\n const randomWait = Math.round(\n // A fraction of the backoff value to add/subtract.\n // Deviation: changes multiplication order to improve readability.\n RANDOM_FACTOR *\n currBaseValue *\n // A random float (rounded to int by Math.round above) in the range [-1, 1]. Determines\n // if we add or subtract.\n (Math.random() - 0.5) *\n 2\n );\n\n // Limits backoff to max to avoid effectively permanent backoff.\n return Math.min(MAX_VALUE_MILLIS, currBaseValue + randomWait);\n}\n", "/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Provide English ordinal letters after a number\n */\nexport function ordinal(i: number): string {\n if (!Number.isFinite(i)) {\n return `${i}`;\n }\n return i + indicator(i);\n}\n\nfunction indicator(i: number): string {\n i = Math.abs(i);\n const cent = i % 100;\n if (cent >= 10 && cent <= 20) {\n return 'th';\n }\n const dec = i % 10;\n if (dec === 1) {\n return 'st';\n }\n if (dec === 2) {\n return 'nd';\n }\n if (dec === 3) {\n return 'rd';\n }\n return 'th';\n}\n", "/**\n * @license\n * Copyright 2021 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport interface Compat {\n _delegate: T;\n}\n\nexport function getModularInstance(\n service: Compat | ExpService\n): ExpService {\n if (service && (service as Compat)._delegate) {\n return (service as Compat)._delegate;\n } else {\n return service as ExpService;\n }\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n InstantiationMode,\n InstanceFactory,\n ComponentType,\n Dictionary,\n Name,\n onInstanceCreatedCallback\n} from './types';\n\n/**\n * Component for service name T, e.g. `auth`, `auth-internal`\n */\nexport class Component {\n multipleInstances = false;\n /**\n * Properties to be added to the service namespace\n */\n serviceProps: Dictionary = {};\n\n instantiationMode = InstantiationMode.LAZY;\n\n onInstanceCreated: onInstanceCreatedCallback | null = null;\n\n /**\n *\n * @param name The public service name, e.g. app, auth, firestore, database\n * @param instanceFactory Service factory responsible for creating the public interface\n * @param type whether the service provided by the component is public or private\n */\n constructor(\n readonly name: T,\n readonly instanceFactory: InstanceFactory,\n readonly type: ComponentType\n ) {}\n\n setInstantiationMode(mode: InstantiationMode): this {\n this.instantiationMode = mode;\n return this;\n }\n\n setMultipleInstances(multipleInstances: boolean): this {\n this.multipleInstances = multipleInstances;\n return this;\n }\n\n setServiceProps(props: Dictionary): this {\n this.serviceProps = props;\n return this;\n }\n\n setInstanceCreatedCallback(callback: onInstanceCreatedCallback): this {\n this.onInstanceCreated = callback;\n return this;\n }\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport const DEFAULT_ENTRY_NAME = '[DEFAULT]';\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Deferred } from '@firebase/util';\nimport { ComponentContainer } from './component_container';\nimport { DEFAULT_ENTRY_NAME } from './constants';\nimport {\n InitializeOptions,\n InstantiationMode,\n Name,\n NameServiceMapping,\n OnInitCallBack\n} from './types';\nimport { Component } from './component';\n\n/**\n * Provider for instance for service name T, e.g. 'auth', 'auth-internal'\n * NameServiceMapping[T] is an alias for the type of the instance\n */\nexport class Provider {\n private component: Component | null = null;\n private readonly instances: Map = new Map();\n private readonly instancesDeferred: Map<\n string,\n Deferred\n > = new Map();\n private readonly instancesOptions: Map> =\n new Map();\n private onInitCallbacks: Map>> = new Map();\n\n constructor(\n private readonly name: T,\n private readonly container: ComponentContainer\n ) {}\n\n /**\n * @param identifier A provider can provide mulitple instances of a service\n * if this.component.multipleInstances is true.\n */\n get(identifier?: string): Promise {\n // if multipleInstances is not supported, use the default name\n const normalizedIdentifier = this.normalizeInstanceIdentifier(identifier);\n\n if (!this.instancesDeferred.has(normalizedIdentifier)) {\n const deferred = new Deferred();\n this.instancesDeferred.set(normalizedIdentifier, deferred);\n\n if (\n this.isInitialized(normalizedIdentifier) ||\n this.shouldAutoInitialize()\n ) {\n // initialize the service if it can be auto-initialized\n try {\n const instance = this.getOrInitializeService({\n instanceIdentifier: normalizedIdentifier\n });\n if (instance) {\n deferred.resolve(instance);\n }\n } catch (e) {\n // when the instance factory throws an exception during get(), it should not cause\n // a fatal error. We just return the unresolved promise in this case.\n }\n }\n }\n\n return this.instancesDeferred.get(normalizedIdentifier)!.promise;\n }\n\n /**\n *\n * @param options.identifier A provider can provide mulitple instances of a service\n * if this.component.multipleInstances is true.\n * @param options.optional If optional is false or not provided, the method throws an error when\n * the service is not immediately available.\n * If optional is true, the method returns null if the service is not immediately available.\n */\n getImmediate(options: {\n identifier?: string;\n optional: true;\n }): NameServiceMapping[T] | null;\n getImmediate(options?: {\n identifier?: string;\n optional?: false;\n }): NameServiceMapping[T];\n getImmediate(options?: {\n identifier?: string;\n optional?: boolean;\n }): NameServiceMapping[T] | null {\n // if multipleInstances is not supported, use the default name\n const normalizedIdentifier = this.normalizeInstanceIdentifier(\n options?.identifier\n );\n const optional = options?.optional ?? false;\n\n if (\n this.isInitialized(normalizedIdentifier) ||\n this.shouldAutoInitialize()\n ) {\n try {\n return this.getOrInitializeService({\n instanceIdentifier: normalizedIdentifier\n });\n } catch (e) {\n if (optional) {\n return null;\n } else {\n throw e;\n }\n }\n } else {\n // In case a component is not initialized and should/can not be auto-initialized at the moment, return null if the optional flag is set, or throw\n if (optional) {\n return null;\n } else {\n throw Error(`Service ${this.name} is not available`);\n }\n }\n }\n\n getComponent(): Component | null {\n return this.component;\n }\n\n setComponent(component: Component): void {\n if (component.name !== this.name) {\n throw Error(\n `Mismatching Component ${component.name} for Provider ${this.name}.`\n );\n }\n\n if (this.component) {\n throw Error(`Component for ${this.name} has already been provided`);\n }\n\n this.component = component;\n\n // return early without attempting to initialize the component if the component requires explicit initialization (calling `Provider.initialize()`)\n if (!this.shouldAutoInitialize()) {\n return;\n }\n\n // if the service is eager, initialize the default instance\n if (isComponentEager(component)) {\n try {\n this.getOrInitializeService({ instanceIdentifier: DEFAULT_ENTRY_NAME });\n } catch (e) {\n // when the instance factory for an eager Component throws an exception during the eager\n // initialization, it should not cause a fatal error.\n // TODO: Investigate if we need to make it configurable, because some component may want to cause\n // a fatal error in this case?\n }\n }\n\n // Create service instances for the pending promises and resolve them\n // NOTE: if this.multipleInstances is false, only the default instance will be created\n // and all promises with resolve with it regardless of the identifier.\n for (const [\n instanceIdentifier,\n instanceDeferred\n ] of this.instancesDeferred.entries()) {\n const normalizedIdentifier =\n this.normalizeInstanceIdentifier(instanceIdentifier);\n\n try {\n // `getOrInitializeService()` should always return a valid instance since a component is guaranteed. use ! to make typescript happy.\n const instance = this.getOrInitializeService({\n instanceIdentifier: normalizedIdentifier\n })!;\n instanceDeferred.resolve(instance);\n } catch (e) {\n // when the instance factory throws an exception, it should not cause\n // a fatal error. We just leave the promise unresolved.\n }\n }\n }\n\n clearInstance(identifier: string = DEFAULT_ENTRY_NAME): void {\n this.instancesDeferred.delete(identifier);\n this.instancesOptions.delete(identifier);\n this.instances.delete(identifier);\n }\n\n // app.delete() will call this method on every provider to delete the services\n // TODO: should we mark the provider as deleted?\n async delete(): Promise {\n const services = Array.from(this.instances.values());\n\n await Promise.all([\n ...services\n .filter(service => 'INTERNAL' in service) // legacy services\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n .map(service => (service as any).INTERNAL!.delete()),\n ...services\n .filter(service => '_delete' in service) // modularized services\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n .map(service => (service as any)._delete())\n ]);\n }\n\n isComponentSet(): boolean {\n return this.component != null;\n }\n\n isInitialized(identifier: string = DEFAULT_ENTRY_NAME): boolean {\n return this.instances.has(identifier);\n }\n\n getOptions(identifier: string = DEFAULT_ENTRY_NAME): Record {\n return this.instancesOptions.get(identifier) || {};\n }\n\n initialize(opts: InitializeOptions = {}): NameServiceMapping[T] {\n const { options = {} } = opts;\n const normalizedIdentifier = this.normalizeInstanceIdentifier(\n opts.instanceIdentifier\n );\n if (this.isInitialized(normalizedIdentifier)) {\n throw Error(\n `${this.name}(${normalizedIdentifier}) has already been initialized`\n );\n }\n\n if (!this.isComponentSet()) {\n throw Error(`Component ${this.name} has not been registered yet`);\n }\n\n const instance = this.getOrInitializeService({\n instanceIdentifier: normalizedIdentifier,\n options\n })!;\n\n // resolve any pending promise waiting for the service instance\n for (const [\n instanceIdentifier,\n instanceDeferred\n ] of this.instancesDeferred.entries()) {\n const normalizedDeferredIdentifier =\n this.normalizeInstanceIdentifier(instanceIdentifier);\n if (normalizedIdentifier === normalizedDeferredIdentifier) {\n instanceDeferred.resolve(instance);\n }\n }\n\n return instance;\n }\n\n /**\n *\n * @param callback - a function that will be invoked after the provider has been initialized by calling provider.initialize().\n * The function is invoked SYNCHRONOUSLY, so it should not execute any longrunning tasks in order to not block the program.\n *\n * @param identifier An optional instance identifier\n * @returns a function to unregister the callback\n */\n onInit(callback: OnInitCallBack, identifier?: string): () => void {\n const normalizedIdentifier = this.normalizeInstanceIdentifier(identifier);\n const existingCallbacks =\n this.onInitCallbacks.get(normalizedIdentifier) ??\n new Set>();\n existingCallbacks.add(callback);\n this.onInitCallbacks.set(normalizedIdentifier, existingCallbacks);\n\n const existingInstance = this.instances.get(normalizedIdentifier);\n if (existingInstance) {\n callback(existingInstance, normalizedIdentifier);\n }\n\n return () => {\n existingCallbacks.delete(callback);\n };\n }\n\n /**\n * Invoke onInit callbacks synchronously\n * @param instance the service instance`\n */\n private invokeOnInitCallbacks(\n instance: NameServiceMapping[T],\n identifier: string\n ): void {\n const callbacks = this.onInitCallbacks.get(identifier);\n if (!callbacks) {\n return;\n }\n for (const callback of callbacks) {\n try {\n callback(instance, identifier);\n } catch {\n // ignore errors in the onInit callback\n }\n }\n }\n\n private getOrInitializeService({\n instanceIdentifier,\n options = {}\n }: {\n instanceIdentifier: string;\n options?: Record;\n }): NameServiceMapping[T] | null {\n let instance = this.instances.get(instanceIdentifier);\n if (!instance && this.component) {\n instance = this.component.instanceFactory(this.container, {\n instanceIdentifier: normalizeIdentifierForFactory(instanceIdentifier),\n options\n });\n this.instances.set(instanceIdentifier, instance);\n this.instancesOptions.set(instanceIdentifier, options);\n\n /**\n * Invoke onInit listeners.\n * Note this.component.onInstanceCreated is different, which is used by the component creator,\n * while onInit listeners are registered by consumers of the provider.\n */\n this.invokeOnInitCallbacks(instance, instanceIdentifier);\n\n /**\n * Order is important\n * onInstanceCreated() should be called after this.instances.set(instanceIdentifier, instance); which\n * makes `isInitialized()` return true.\n */\n if (this.component.onInstanceCreated) {\n try {\n this.component.onInstanceCreated(\n this.container,\n instanceIdentifier,\n instance\n );\n } catch {\n // ignore errors in the onInstanceCreatedCallback\n }\n }\n }\n\n return instance || null;\n }\n\n private normalizeInstanceIdentifier(\n identifier: string = DEFAULT_ENTRY_NAME\n ): string {\n if (this.component) {\n return this.component.multipleInstances ? identifier : DEFAULT_ENTRY_NAME;\n } else {\n return identifier; // assume multiple instances are supported before the component is provided.\n }\n }\n\n private shouldAutoInitialize(): boolean {\n return (\n !!this.component &&\n this.component.instantiationMode !== InstantiationMode.EXPLICIT\n );\n }\n}\n\n// undefined should be passed to the service factory for the default instance\nfunction normalizeIdentifierForFactory(identifier: string): string | undefined {\n return identifier === DEFAULT_ENTRY_NAME ? undefined : identifier;\n}\n\nfunction isComponentEager(component: Component): boolean {\n return component.instantiationMode === InstantiationMode.EAGER;\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Provider } from './provider';\nimport { Component } from './component';\nimport { Name } from './types';\n\n/**\n * ComponentContainer that provides Providers for service name T, e.g. `auth`, `auth-internal`\n */\nexport class ComponentContainer {\n private readonly providers = new Map>();\n\n constructor(private readonly name: string) {}\n\n /**\n *\n * @param component Component being added\n * @param overwrite When a component with the same name has already been registered,\n * if overwrite is true: overwrite the existing component with the new component and create a new\n * provider with the new component. It can be useful in tests where you want to use different mocks\n * for different tests.\n * if overwrite is false: throw an exception\n */\n addComponent(component: Component): void {\n const provider = this.getProvider(component.name);\n if (provider.isComponentSet()) {\n throw new Error(\n `Component ${component.name} has already been registered with ${this.name}`\n );\n }\n\n provider.setComponent(component);\n }\n\n addOrOverwriteComponent(component: Component): void {\n const provider = this.getProvider(component.name);\n if (provider.isComponentSet()) {\n // delete the existing provider from the container, so we can register the new component\n this.providers.delete(component.name);\n }\n\n this.addComponent(component);\n }\n\n /**\n * getProvider provides a type safe interface where it can only be called with a field name\n * present in NameServiceMapping interface.\n *\n * Firebase SDKs providing services should extend NameServiceMapping interface to register\n * themselves.\n */\n getProvider(name: T): Provider {\n if (this.providers.has(name)) {\n return this.providers.get(name) as unknown as Provider;\n }\n\n // create a Provider for a service that hasn't registered with Firebase\n const provider = new Provider(name, this);\n this.providers.set(name, provider as unknown as Provider);\n\n return provider as Provider;\n }\n\n getProviders(): Array> {\n return Array.from(this.providers.values());\n }\n}\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport type LogLevelString =\n | 'debug'\n | 'verbose'\n | 'info'\n | 'warn'\n | 'error'\n | 'silent';\n\nexport interface LogOptions {\n level: LogLevelString;\n}\n\nexport type LogCallback = (callbackParams: LogCallbackParams) => void;\n\nexport interface LogCallbackParams {\n level: LogLevelString;\n message: string;\n args: unknown[];\n type: string;\n}\n\n/**\n * A container for all of the Logger instances\n */\nexport const instances: Logger[] = [];\n\n/**\n * The JS SDK supports 5 log levels and also allows a user the ability to\n * silence the logs altogether.\n *\n * The order is a follows:\n * DEBUG < VERBOSE < INFO < WARN < ERROR\n *\n * All of the log types above the current log level will be captured (i.e. if\n * you set the log level to `INFO`, errors will still be logged, but `DEBUG` and\n * `VERBOSE` logs will not)\n */\nexport enum LogLevel {\n DEBUG,\n VERBOSE,\n INFO,\n WARN,\n ERROR,\n SILENT\n}\n\nconst levelStringToEnum: { [key in LogLevelString]: LogLevel } = {\n 'debug': LogLevel.DEBUG,\n 'verbose': LogLevel.VERBOSE,\n 'info': LogLevel.INFO,\n 'warn': LogLevel.WARN,\n 'error': LogLevel.ERROR,\n 'silent': LogLevel.SILENT\n};\n\n/**\n * The default log level\n */\nconst defaultLogLevel: LogLevel = LogLevel.INFO;\n\n/**\n * We allow users the ability to pass their own log handler. We will pass the\n * type of log, the current log level, and any other arguments passed (i.e. the\n * messages that the user wants to log) to this function.\n */\nexport type LogHandler = (\n loggerInstance: Logger,\n logType: LogLevel,\n ...args: unknown[]\n) => void;\n\n/**\n * By default, `console.debug` is not displayed in the developer console (in\n * chrome). To avoid forcing users to have to opt-in to these logs twice\n * (i.e. once for firebase, and once in the console), we are sending `DEBUG`\n * logs to the `console.log` function.\n */\nconst ConsoleMethod = {\n [LogLevel.DEBUG]: 'log',\n [LogLevel.VERBOSE]: 'log',\n [LogLevel.INFO]: 'info',\n [LogLevel.WARN]: 'warn',\n [LogLevel.ERROR]: 'error'\n};\n\n/**\n * The default log handler will forward DEBUG, VERBOSE, INFO, WARN, and ERROR\n * messages on to their corresponding console counterparts (if the log method\n * is supported by the current log level)\n */\nconst defaultLogHandler: LogHandler = (instance, logType, ...args): void => {\n if (logType < instance.logLevel) {\n return;\n }\n const now = new Date().toISOString();\n const method = ConsoleMethod[logType as keyof typeof ConsoleMethod];\n if (method) {\n console[method as 'log' | 'info' | 'warn' | 'error'](\n `[${now}] ${instance.name}:`,\n ...args\n );\n } else {\n throw new Error(\n `Attempted to log a message with an invalid logType (value: ${logType})`\n );\n }\n};\n\nexport class Logger {\n /**\n * Gives you an instance of a Logger to capture messages according to\n * Firebase's logging scheme.\n *\n * @param name The name that the logs will be associated with\n */\n constructor(public name: string) {\n /**\n * Capture the current instance for later use\n */\n instances.push(this);\n }\n\n /**\n * The log level of the given Logger instance.\n */\n private _logLevel = defaultLogLevel;\n\n get logLevel(): LogLevel {\n return this._logLevel;\n }\n\n set logLevel(val: LogLevel) {\n if (!(val in LogLevel)) {\n throw new TypeError(`Invalid value \"${val}\" assigned to \\`logLevel\\``);\n }\n this._logLevel = val;\n }\n\n // Workaround for setter/getter having to be the same type.\n setLogLevel(val: LogLevel | LogLevelString): void {\n this._logLevel = typeof val === 'string' ? levelStringToEnum[val] : val;\n }\n\n /**\n * The main (internal) log handler for the Logger instance.\n * Can be set to a new function in internal package code but not by user.\n */\n private _logHandler: LogHandler = defaultLogHandler;\n get logHandler(): LogHandler {\n return this._logHandler;\n }\n set logHandler(val: LogHandler) {\n if (typeof val !== 'function') {\n throw new TypeError('Value assigned to `logHandler` must be a function');\n }\n this._logHandler = val;\n }\n\n /**\n * The optional, additional, user-defined log handler for the Logger instance.\n */\n private _userLogHandler: LogHandler | null = null;\n get userLogHandler(): LogHandler | null {\n return this._userLogHandler;\n }\n set userLogHandler(val: LogHandler | null) {\n this._userLogHandler = val;\n }\n\n /**\n * The functions below are all based on the `console` interface\n */\n\n debug(...args: unknown[]): void {\n this._userLogHandler && this._userLogHandler(this, LogLevel.DEBUG, ...args);\n this._logHandler(this, LogLevel.DEBUG, ...args);\n }\n log(...args: unknown[]): void {\n this._userLogHandler &&\n this._userLogHandler(this, LogLevel.VERBOSE, ...args);\n this._logHandler(this, LogLevel.VERBOSE, ...args);\n }\n info(...args: unknown[]): void {\n this._userLogHandler && this._userLogHandler(this, LogLevel.INFO, ...args);\n this._logHandler(this, LogLevel.INFO, ...args);\n }\n warn(...args: unknown[]): void {\n this._userLogHandler && this._userLogHandler(this, LogLevel.WARN, ...args);\n this._logHandler(this, LogLevel.WARN, ...args);\n }\n error(...args: unknown[]): void {\n this._userLogHandler && this._userLogHandler(this, LogLevel.ERROR, ...args);\n this._logHandler(this, LogLevel.ERROR, ...args);\n }\n}\n\nexport function setLogLevel(level: LogLevelString | LogLevel): void {\n instances.forEach(inst => {\n inst.setLogLevel(level);\n });\n}\n\nexport function setUserLogHandler(\n logCallback: LogCallback | null,\n options?: LogOptions\n): void {\n for (const instance of instances) {\n let customLogLevel: LogLevel | null = null;\n if (options && options.level) {\n customLogLevel = levelStringToEnum[options.level];\n }\n if (logCallback === null) {\n instance.userLogHandler = null;\n } else {\n instance.userLogHandler = (\n instance: Logger,\n level: LogLevel,\n ...args: unknown[]\n ) => {\n const message = args\n .map(arg => {\n if (arg == null) {\n return null;\n } else if (typeof arg === 'string') {\n return arg;\n } else if (typeof arg === 'number' || typeof arg === 'boolean') {\n return arg.toString();\n } else if (arg instanceof Error) {\n return arg.message;\n } else {\n try {\n return JSON.stringify(arg);\n } catch (ignored) {\n return null;\n }\n }\n })\n .filter(arg => arg)\n .join(' ');\n if (level >= (customLogLevel ?? instance.logLevel)) {\n logCallback({\n level: LogLevel[level].toLowerCase() as LogLevelString,\n message,\n args,\n type: instance.name\n });\n }\n };\n }\n }\n}\n", "const instanceOfAny = (object, constructors) => constructors.some((c) => object instanceof c);\n\nlet idbProxyableTypes;\nlet cursorAdvanceMethods;\n// This is a function to prevent it throwing up in node environments.\nfunction getIdbProxyableTypes() {\n return (idbProxyableTypes ||\n (idbProxyableTypes = [\n IDBDatabase,\n IDBObjectStore,\n IDBIndex,\n IDBCursor,\n IDBTransaction,\n ]));\n}\n// This is a function to prevent it throwing up in node environments.\nfunction getCursorAdvanceMethods() {\n return (cursorAdvanceMethods ||\n (cursorAdvanceMethods = [\n IDBCursor.prototype.advance,\n IDBCursor.prototype.continue,\n IDBCursor.prototype.continuePrimaryKey,\n ]));\n}\nconst cursorRequestMap = new WeakMap();\nconst transactionDoneMap = new WeakMap();\nconst transactionStoreNamesMap = new WeakMap();\nconst transformCache = new WeakMap();\nconst reverseTransformCache = new WeakMap();\nfunction promisifyRequest(request) {\n const promise = new Promise((resolve, reject) => {\n const unlisten = () => {\n request.removeEventListener('success', success);\n request.removeEventListener('error', error);\n };\n const success = () => {\n resolve(wrap(request.result));\n unlisten();\n };\n const error = () => {\n reject(request.error);\n unlisten();\n };\n request.addEventListener('success', success);\n request.addEventListener('error', error);\n });\n promise\n .then((value) => {\n // Since cursoring reuses the IDBRequest (*sigh*), we cache it for later retrieval\n // (see wrapFunction).\n if (value instanceof IDBCursor) {\n cursorRequestMap.set(value, request);\n }\n // Catching to avoid \"Uncaught Promise exceptions\"\n })\n .catch(() => { });\n // This mapping exists in reverseTransformCache but doesn't doesn't exist in transformCache. This\n // is because we create many promises from a single IDBRequest.\n reverseTransformCache.set(promise, request);\n return promise;\n}\nfunction cacheDonePromiseForTransaction(tx) {\n // Early bail if we've already created a done promise for this transaction.\n if (transactionDoneMap.has(tx))\n return;\n const done = new Promise((resolve, reject) => {\n const unlisten = () => {\n tx.removeEventListener('complete', complete);\n tx.removeEventListener('error', error);\n tx.removeEventListener('abort', error);\n };\n const complete = () => {\n resolve();\n unlisten();\n };\n const error = () => {\n reject(tx.error || new DOMException('AbortError', 'AbortError'));\n unlisten();\n };\n tx.addEventListener('complete', complete);\n tx.addEventListener('error', error);\n tx.addEventListener('abort', error);\n });\n // Cache it for later retrieval.\n transactionDoneMap.set(tx, done);\n}\nlet idbProxyTraps = {\n get(target, prop, receiver) {\n if (target instanceof IDBTransaction) {\n // Special handling for transaction.done.\n if (prop === 'done')\n return transactionDoneMap.get(target);\n // Polyfill for objectStoreNames because of Edge.\n if (prop === 'objectStoreNames') {\n return target.objectStoreNames || transactionStoreNamesMap.get(target);\n }\n // Make tx.store return the only store in the transaction, or undefined if there are many.\n if (prop === 'store') {\n return receiver.objectStoreNames[1]\n ? undefined\n : receiver.objectStore(receiver.objectStoreNames[0]);\n }\n }\n // Else transform whatever we get back.\n return wrap(target[prop]);\n },\n set(target, prop, value) {\n target[prop] = value;\n return true;\n },\n has(target, prop) {\n if (target instanceof IDBTransaction &&\n (prop === 'done' || prop === 'store')) {\n return true;\n }\n return prop in target;\n },\n};\nfunction replaceTraps(callback) {\n idbProxyTraps = callback(idbProxyTraps);\n}\nfunction wrapFunction(func) {\n // Due to expected object equality (which is enforced by the caching in `wrap`), we\n // only create one new func per func.\n // Edge doesn't support objectStoreNames (booo), so we polyfill it here.\n if (func === IDBDatabase.prototype.transaction &&\n !('objectStoreNames' in IDBTransaction.prototype)) {\n return function (storeNames, ...args) {\n const tx = func.call(unwrap(this), storeNames, ...args);\n transactionStoreNamesMap.set(tx, storeNames.sort ? storeNames.sort() : [storeNames]);\n return wrap(tx);\n };\n }\n // Cursor methods are special, as the behaviour is a little more different to standard IDB. In\n // IDB, you advance the cursor and wait for a new 'success' on the IDBRequest that gave you the\n // cursor. It's kinda like a promise that can resolve with many values. That doesn't make sense\n // with real promises, so each advance methods returns a new promise for the cursor object, or\n // undefined if the end of the cursor has been reached.\n if (getCursorAdvanceMethods().includes(func)) {\n return function (...args) {\n // Calling the original function with the proxy as 'this' causes ILLEGAL INVOCATION, so we use\n // the original object.\n func.apply(unwrap(this), args);\n return wrap(cursorRequestMap.get(this));\n };\n }\n return function (...args) {\n // Calling the original function with the proxy as 'this' causes ILLEGAL INVOCATION, so we use\n // the original object.\n return wrap(func.apply(unwrap(this), args));\n };\n}\nfunction transformCachableValue(value) {\n if (typeof value === 'function')\n return wrapFunction(value);\n // This doesn't return, it just creates a 'done' promise for the transaction,\n // which is later returned for transaction.done (see idbObjectHandler).\n if (value instanceof IDBTransaction)\n cacheDonePromiseForTransaction(value);\n if (instanceOfAny(value, getIdbProxyableTypes()))\n return new Proxy(value, idbProxyTraps);\n // Return the same value back if we're not going to transform it.\n return value;\n}\nfunction wrap(value) {\n // We sometimes generate multiple promises from a single IDBRequest (eg when cursoring), because\n // IDB is weird and a single IDBRequest can yield many responses, so these can't be cached.\n if (value instanceof IDBRequest)\n return promisifyRequest(value);\n // If we've already transformed this value before, reuse the transformed value.\n // This is faster, but it also provides object equality.\n if (transformCache.has(value))\n return transformCache.get(value);\n const newValue = transformCachableValue(value);\n // Not all types are transformed.\n // These may be primitive types, so they can't be WeakMap keys.\n if (newValue !== value) {\n transformCache.set(value, newValue);\n reverseTransformCache.set(newValue, value);\n }\n return newValue;\n}\nconst unwrap = (value) => reverseTransformCache.get(value);\n\nexport { reverseTransformCache as a, instanceOfAny as i, replaceTraps as r, unwrap as u, wrap as w };\n", "import { w as wrap, r as replaceTraps } from './wrap-idb-value.js';\nexport { u as unwrap, w as wrap } from './wrap-idb-value.js';\n\n/**\n * Open a database.\n *\n * @param name Name of the database.\n * @param version Schema version.\n * @param callbacks Additional callbacks.\n */\nfunction openDB(name, version, { blocked, upgrade, blocking, terminated } = {}) {\n const request = indexedDB.open(name, version);\n const openPromise = wrap(request);\n if (upgrade) {\n request.addEventListener('upgradeneeded', (event) => {\n upgrade(wrap(request.result), event.oldVersion, event.newVersion, wrap(request.transaction));\n });\n }\n if (blocked)\n request.addEventListener('blocked', () => blocked());\n openPromise\n .then((db) => {\n if (terminated)\n db.addEventListener('close', () => terminated());\n if (blocking)\n db.addEventListener('versionchange', () => blocking());\n })\n .catch(() => { });\n return openPromise;\n}\n/**\n * Delete a database.\n *\n * @param name Name of the database.\n */\nfunction deleteDB(name, { blocked } = {}) {\n const request = indexedDB.deleteDatabase(name);\n if (blocked)\n request.addEventListener('blocked', () => blocked());\n return wrap(request).then(() => undefined);\n}\n\nconst readMethods = ['get', 'getKey', 'getAll', 'getAllKeys', 'count'];\nconst writeMethods = ['put', 'add', 'delete', 'clear'];\nconst cachedMethods = new Map();\nfunction getMethod(target, prop) {\n if (!(target instanceof IDBDatabase &&\n !(prop in target) &&\n typeof prop === 'string')) {\n return;\n }\n if (cachedMethods.get(prop))\n return cachedMethods.get(prop);\n const targetFuncName = prop.replace(/FromIndex$/, '');\n const useIndex = prop !== targetFuncName;\n const isWrite = writeMethods.includes(targetFuncName);\n if (\n // Bail if the target doesn't exist on the target. Eg, getAll isn't in Edge.\n !(targetFuncName in (useIndex ? IDBIndex : IDBObjectStore).prototype) ||\n !(isWrite || readMethods.includes(targetFuncName))) {\n return;\n }\n const method = async function (storeName, ...args) {\n // isWrite ? 'readwrite' : undefined gzipps better, but fails in Edge :(\n const tx = this.transaction(storeName, isWrite ? 'readwrite' : 'readonly');\n let target = tx.store;\n if (useIndex)\n target = target.index(args.shift());\n // Must reject if op rejects.\n // If it's a write operation, must reject if tx.done rejects.\n // Must reject with op rejection first.\n // Must resolve with op value.\n // Must handle both promises (no unhandled rejections)\n return (await Promise.all([\n target[targetFuncName](...args),\n isWrite && tx.done,\n ]))[0];\n };\n cachedMethods.set(prop, method);\n return method;\n}\nreplaceTraps((oldTraps) => ({\n ...oldTraps,\n get: (target, prop, receiver) => getMethod(target, prop) || oldTraps.get(target, prop, receiver),\n has: (target, prop) => !!getMethod(target, prop) || oldTraps.has(target, prop),\n}));\n\nexport { deleteDB, openDB };\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n ComponentContainer,\n ComponentType,\n Provider,\n Name\n} from '@firebase/component';\nimport { PlatformLoggerService, VersionService } from './types';\n\nexport class PlatformLoggerServiceImpl implements PlatformLoggerService {\n constructor(private readonly container: ComponentContainer) {}\n // In initial implementation, this will be called by installations on\n // auth token refresh, and installations will send this string.\n getPlatformInfoString(): string {\n const providers = this.container.getProviders();\n // Loop through providers and get library/version pairs from any that are\n // version components.\n return providers\n .map(provider => {\n if (isVersionServiceProvider(provider)) {\n const service = provider.getImmediate() as VersionService;\n return `${service.library}/${service.version}`;\n } else {\n return null;\n }\n })\n .filter(logString => logString)\n .join(' ');\n }\n}\n/**\n *\n * @param provider check if this provider provides a VersionService\n *\n * NOTE: Using Provider<'app-version'> is a hack to indicate that the provider\n * provides VersionService. The provider is not necessarily a 'app-version'\n * provider.\n */\nfunction isVersionServiceProvider(provider: Provider): boolean {\n const component = provider.getComponent();\n return component?.type === ComponentType.VERSION;\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Logger } from '@firebase/logger';\n\nexport const logger = new Logger('@firebase/app');\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { name as appName } from '../package.json';\nimport { name as appCompatName } from '../../app-compat/package.json';\nimport { name as analyticsCompatName } from '../../../packages/analytics-compat/package.json';\nimport { name as analyticsName } from '../../../packages/analytics/package.json';\nimport { name as appCheckCompatName } from '../../../packages/app-check-compat/package.json';\nimport { name as appCheckName } from '../../../packages/app-check/package.json';\nimport { name as authName } from '../../../packages/auth/package.json';\nimport { name as authCompatName } from '../../../packages/auth-compat/package.json';\nimport { name as databaseName } from '../../../packages/database/package.json';\nimport { name as databaseCompatName } from '../../../packages/database-compat/package.json';\nimport { name as functionsName } from '../../../packages/functions/package.json';\nimport { name as functionsCompatName } from '../../../packages/functions-compat/package.json';\nimport { name as installationsName } from '../../../packages/installations/package.json';\nimport { name as installationsCompatName } from '../../../packages/installations-compat/package.json';\nimport { name as messagingName } from '../../../packages/messaging/package.json';\nimport { name as messagingCompatName } from '../../../packages/messaging-compat/package.json';\nimport { name as performanceName } from '../../../packages/performance/package.json';\nimport { name as performanceCompatName } from '../../../packages/performance-compat/package.json';\nimport { name as remoteConfigName } from '../../../packages/remote-config/package.json';\nimport { name as remoteConfigCompatName } from '../../../packages/remote-config-compat/package.json';\nimport { name as storageName } from '../../../packages/storage/package.json';\nimport { name as storageCompatName } from '../../../packages/storage-compat/package.json';\nimport { name as firestoreName } from '../../../packages/firestore/package.json';\nimport { name as firestoreCompatName } from '../../../packages/firestore-compat/package.json';\nimport { name as packageName } from '../../../packages/firebase/package.json';\n\n/**\n * The default app name\n *\n * @internal\n */\nexport const DEFAULT_ENTRY_NAME = '[DEFAULT]';\n\nexport const PLATFORM_LOG_STRING = {\n [appName]: 'fire-core',\n [appCompatName]: 'fire-core-compat',\n [analyticsName]: 'fire-analytics',\n [analyticsCompatName]: 'fire-analytics-compat',\n [appCheckName]: 'fire-app-check',\n [appCheckCompatName]: 'fire-app-check-compat',\n [authName]: 'fire-auth',\n [authCompatName]: 'fire-auth-compat',\n [databaseName]: 'fire-rtdb',\n [databaseCompatName]: 'fire-rtdb-compat',\n [functionsName]: 'fire-fn',\n [functionsCompatName]: 'fire-fn-compat',\n [installationsName]: 'fire-iid',\n [installationsCompatName]: 'fire-iid-compat',\n [messagingName]: 'fire-fcm',\n [messagingCompatName]: 'fire-fcm-compat',\n [performanceName]: 'fire-perf',\n [performanceCompatName]: 'fire-perf-compat',\n [remoteConfigName]: 'fire-rc',\n [remoteConfigCompatName]: 'fire-rc-compat',\n [storageName]: 'fire-gcs',\n [storageCompatName]: 'fire-gcs-compat',\n [firestoreName]: 'fire-fst',\n [firestoreCompatName]: 'fire-fst-compat',\n 'fire-js': 'fire-js', // Platform identifier for JS SDK.\n [packageName]: 'fire-js-all'\n} as const;\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { FirebaseApp } from './public-types';\nimport { Component, Provider, Name } from '@firebase/component';\nimport { logger } from './logger';\nimport { DEFAULT_ENTRY_NAME } from './constants';\nimport { FirebaseAppImpl } from './firebaseApp';\n\n/**\n * @internal\n */\nexport const _apps = new Map();\n\n/**\n * Registered components.\n *\n * @internal\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport const _components = new Map>();\n\n/**\n * @param component - the component being added to this app's container\n *\n * @internal\n */\nexport function _addComponent(\n app: FirebaseApp,\n component: Component\n): void {\n try {\n (app as FirebaseAppImpl).container.addComponent(component);\n } catch (e) {\n logger.debug(\n `Component ${component.name} failed to register with FirebaseApp ${app.name}`,\n e\n );\n }\n}\n\n/**\n *\n * @internal\n */\nexport function _addOrOverwriteComponent(\n app: FirebaseApp,\n component: Component\n): void {\n (app as FirebaseAppImpl).container.addOrOverwriteComponent(component);\n}\n\n/**\n *\n * @param component - the component to register\n * @returns whether or not the component is registered successfully\n *\n * @internal\n */\nexport function _registerComponent(\n component: Component\n): boolean {\n const componentName = component.name;\n if (_components.has(componentName)) {\n logger.debug(\n `There were multiple attempts to register component ${componentName}.`\n );\n\n return false;\n }\n\n _components.set(componentName, component);\n\n // add the component to existing app instances\n for (const app of _apps.values()) {\n _addComponent(app as FirebaseAppImpl, component);\n }\n\n return true;\n}\n\n/**\n *\n * @param app - FirebaseApp instance\n * @param name - service name\n *\n * @returns the provider for the service with the matching name\n *\n * @internal\n */\nexport function _getProvider(\n app: FirebaseApp,\n name: T\n): Provider {\n const heartbeatController = (app as FirebaseAppImpl).container\n .getProvider('heartbeat')\n .getImmediate({ optional: true });\n if (heartbeatController) {\n void heartbeatController.triggerHeartbeat();\n }\n return (app as FirebaseAppImpl).container.getProvider(name);\n}\n\n/**\n *\n * @param app - FirebaseApp instance\n * @param name - service name\n * @param instanceIdentifier - service instance identifier in case the service supports multiple instances\n *\n * @internal\n */\nexport function _removeServiceInstance(\n app: FirebaseApp,\n name: T,\n instanceIdentifier: string = DEFAULT_ENTRY_NAME\n): void {\n _getProvider(app, name).clearInstance(instanceIdentifier);\n}\n\n/**\n * Test only\n *\n * @internal\n */\nexport function _clearComponents(): void {\n _components.clear();\n}\n\n/**\n * Exported in order to be used in app-compat package\n */\nexport { DEFAULT_ENTRY_NAME as _DEFAULT_ENTRY_NAME };\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ErrorFactory, ErrorMap } from '@firebase/util';\n\nexport const enum AppError {\n NO_APP = 'no-app',\n BAD_APP_NAME = 'bad-app-name',\n DUPLICATE_APP = 'duplicate-app',\n APP_DELETED = 'app-deleted',\n INVALID_APP_ARGUMENT = 'invalid-app-argument',\n INVALID_LOG_ARGUMENT = 'invalid-log-argument',\n IDB_OPEN = 'idb-open',\n IDB_GET = 'idb-get',\n IDB_WRITE = 'idb-set',\n IDB_DELETE = 'idb-delete'\n}\n\nconst ERRORS: ErrorMap = {\n [AppError.NO_APP]:\n \"No Firebase App '{$appName}' has been created - \" +\n 'call Firebase App.initializeApp()',\n [AppError.BAD_APP_NAME]: \"Illegal App name: '{$appName}\",\n [AppError.DUPLICATE_APP]:\n \"Firebase App named '{$appName}' already exists with different options or config\",\n [AppError.APP_DELETED]: \"Firebase App named '{$appName}' already deleted\",\n [AppError.INVALID_APP_ARGUMENT]:\n 'firebase.{$appName}() takes either no argument or a ' +\n 'Firebase App instance.',\n [AppError.INVALID_LOG_ARGUMENT]:\n 'First argument to `onLog` must be null or a function.',\n [AppError.IDB_OPEN]:\n 'Error thrown when opening IndexedDB. Original error: {$originalErrorMessage}.',\n [AppError.IDB_GET]:\n 'Error thrown when reading from IndexedDB. Original error: {$originalErrorMessage}.',\n [AppError.IDB_WRITE]:\n 'Error thrown when writing to IndexedDB. Original error: {$originalErrorMessage}.',\n [AppError.IDB_DELETE]:\n 'Error thrown when deleting from IndexedDB. Original error: {$originalErrorMessage}.'\n};\n\ninterface ErrorParams {\n [AppError.NO_APP]: { appName: string };\n [AppError.BAD_APP_NAME]: { appName: string };\n [AppError.DUPLICATE_APP]: { appName: string };\n [AppError.APP_DELETED]: { appName: string };\n [AppError.INVALID_APP_ARGUMENT]: { appName: string };\n [AppError.IDB_OPEN]: { originalErrorMessage?: string };\n [AppError.IDB_GET]: { originalErrorMessage?: string };\n [AppError.IDB_WRITE]: { originalErrorMessage?: string };\n [AppError.IDB_DELETE]: { originalErrorMessage?: string };\n}\n\nexport const ERROR_FACTORY = new ErrorFactory(\n 'app',\n 'Firebase',\n ERRORS\n);\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n FirebaseApp,\n FirebaseOptions,\n FirebaseAppSettings\n} from './public-types';\nimport {\n ComponentContainer,\n Component,\n ComponentType\n} from '@firebase/component';\nimport { ERROR_FACTORY, AppError } from './errors';\n\nexport class FirebaseAppImpl implements FirebaseApp {\n private readonly _options: FirebaseOptions;\n private readonly _name: string;\n /**\n * Original config values passed in as a constructor parameter.\n * It is only used to compare with another config object to support idempotent initializeApp().\n *\n * Updating automaticDataCollectionEnabled on the App instance will not change its value in _config.\n */\n private readonly _config: Required;\n private _automaticDataCollectionEnabled: boolean;\n private _isDeleted = false;\n private readonly _container: ComponentContainer;\n\n constructor(\n options: FirebaseOptions,\n config: Required,\n container: ComponentContainer\n ) {\n this._options = { ...options };\n this._config = { ...config };\n this._name = config.name;\n this._automaticDataCollectionEnabled =\n config.automaticDataCollectionEnabled;\n this._container = container;\n this.container.addComponent(\n new Component('app', () => this, ComponentType.PUBLIC)\n );\n }\n\n get automaticDataCollectionEnabled(): boolean {\n this.checkDestroyed();\n return this._automaticDataCollectionEnabled;\n }\n\n set automaticDataCollectionEnabled(val: boolean) {\n this.checkDestroyed();\n this._automaticDataCollectionEnabled = val;\n }\n\n get name(): string {\n this.checkDestroyed();\n return this._name;\n }\n\n get options(): FirebaseOptions {\n this.checkDestroyed();\n return this._options;\n }\n\n get config(): Required {\n this.checkDestroyed();\n return this._config;\n }\n\n get container(): ComponentContainer {\n return this._container;\n }\n\n get isDeleted(): boolean {\n return this._isDeleted;\n }\n\n set isDeleted(val: boolean) {\n this._isDeleted = val;\n }\n\n /**\n * This function will throw an Error if the App has already been deleted -\n * use before performing API actions on the App.\n */\n private checkDestroyed(): void {\n if (this.isDeleted) {\n throw ERROR_FACTORY.create(AppError.APP_DELETED, { appName: this._name });\n }\n }\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n FirebaseApp,\n FirebaseOptions,\n FirebaseAppSettings\n} from './public-types';\nimport { DEFAULT_ENTRY_NAME, PLATFORM_LOG_STRING } from './constants';\nimport { ERROR_FACTORY, AppError } from './errors';\nimport {\n ComponentContainer,\n Component,\n Name,\n ComponentType\n} from '@firebase/component';\nimport { version } from '../../firebase/package.json';\nimport { FirebaseAppImpl } from './firebaseApp';\nimport { _apps, _components, _registerComponent } from './internal';\nimport { logger } from './logger';\nimport {\n LogLevelString,\n setLogLevel as setLogLevelImpl,\n LogCallback,\n LogOptions,\n setUserLogHandler\n} from '@firebase/logger';\nimport { deepEqual } from '@firebase/util';\n\nexport { FirebaseError } from '@firebase/util';\n\n/**\n * The current SDK version.\n *\n * @public\n */\nexport const SDK_VERSION = version;\n\n/**\n * Creates and initializes a {@link @firebase/app#FirebaseApp} instance.\n *\n * See\n * {@link\n * https://firebase.google.com/docs/web/setup#add_firebase_to_your_app\n * | Add Firebase to your app} and\n * {@link\n * https://firebase.google.com/docs/web/setup#multiple-projects\n * | Initialize multiple projects} for detailed documentation.\n *\n * @example\n * ```javascript\n *\n * // Initialize default app\n * // Retrieve your own options values by adding a web app on\n * // https://console.firebase.google.com\n * initializeApp({\n * apiKey: \"AIza....\", // Auth / General Use\n * authDomain: \"YOUR_APP.firebaseapp.com\", // Auth with popup/redirect\n * databaseURL: \"https://YOUR_APP.firebaseio.com\", // Realtime Database\n * storageBucket: \"YOUR_APP.appspot.com\", // Storage\n * messagingSenderId: \"123456789\" // Cloud Messaging\n * });\n * ```\n *\n * @example\n * ```javascript\n *\n * // Initialize another app\n * const otherApp = initializeApp({\n * databaseURL: \"https://.firebaseio.com\",\n * storageBucket: \".appspot.com\"\n * }, \"otherApp\");\n * ```\n *\n * @param options - Options to configure the app's services.\n * @param name - Optional name of the app to initialize. If no name\n * is provided, the default is `\"[DEFAULT]\"`.\n *\n * @returns The initialized app.\n *\n * @public\n */\nexport function initializeApp(\n options: FirebaseOptions,\n name?: string\n): FirebaseApp;\n/**\n * Creates and initializes a FirebaseApp instance.\n *\n * @param options - Options to configure the app's services.\n * @param config - FirebaseApp Configuration\n *\n * @public\n */\nexport function initializeApp(\n options: FirebaseOptions,\n config?: FirebaseAppSettings\n): FirebaseApp;\nexport function initializeApp(\n options: FirebaseOptions,\n rawConfig = {}\n): FirebaseApp {\n if (typeof rawConfig !== 'object') {\n const name = rawConfig;\n rawConfig = { name };\n }\n\n const config: Required = {\n name: DEFAULT_ENTRY_NAME,\n automaticDataCollectionEnabled: false,\n ...rawConfig\n };\n const name = config.name;\n\n if (typeof name !== 'string' || !name) {\n throw ERROR_FACTORY.create(AppError.BAD_APP_NAME, {\n appName: String(name)\n });\n }\n\n const existingApp = _apps.get(name) as FirebaseAppImpl;\n if (existingApp) {\n // return the existing app if options and config deep equal the ones in the existing app.\n if (\n deepEqual(options, existingApp.options) &&\n deepEqual(config, existingApp.config)\n ) {\n return existingApp;\n } else {\n throw ERROR_FACTORY.create(AppError.DUPLICATE_APP, { appName: name });\n }\n }\n\n const container = new ComponentContainer(name);\n for (const component of _components.values()) {\n container.addComponent(component);\n }\n\n const newApp = new FirebaseAppImpl(options, config, container);\n\n _apps.set(name, newApp);\n\n return newApp;\n}\n\n/**\n * Retrieves a {@link @firebase/app#FirebaseApp} instance.\n *\n * When called with no arguments, the default app is returned. When an app name\n * is provided, the app corresponding to that name is returned.\n *\n * An exception is thrown if the app being retrieved has not yet been\n * initialized.\n *\n * @example\n * ```javascript\n * // Return the default app\n * const app = getApp();\n * ```\n *\n * @example\n * ```javascript\n * // Return a named app\n * const otherApp = getApp(\"otherApp\");\n * ```\n *\n * @param name - Optional name of the app to return. If no name is\n * provided, the default is `\"[DEFAULT]\"`.\n *\n * @returns The app corresponding to the provided app name.\n * If no app name is provided, the default app is returned.\n *\n * @public\n */\nexport function getApp(name: string = DEFAULT_ENTRY_NAME): FirebaseApp {\n const app = _apps.get(name);\n if (!app) {\n throw ERROR_FACTORY.create(AppError.NO_APP, { appName: name });\n }\n\n return app;\n}\n\n/**\n * A (read-only) array of all initialized apps.\n * @public\n */\nexport function getApps(): FirebaseApp[] {\n return Array.from(_apps.values());\n}\n\n/**\n * Renders this app unusable and frees the resources of all associated\n * services.\n *\n * @example\n * ```javascript\n * deleteApp(app)\n * .then(function() {\n * console.log(\"App deleted successfully\");\n * })\n * .catch(function(error) {\n * console.log(\"Error deleting app:\", error);\n * });\n * ```\n *\n * @public\n */\nexport async function deleteApp(app: FirebaseApp): Promise {\n const name = app.name;\n if (_apps.has(name)) {\n _apps.delete(name);\n await Promise.all(\n (app as FirebaseAppImpl).container\n .getProviders()\n .map(provider => provider.delete())\n );\n (app as FirebaseAppImpl).isDeleted = true;\n }\n}\n\n/**\n * Registers a library's name and version for platform logging purposes.\n * @param library - Name of 1p or 3p library (e.g. firestore, angularfire)\n * @param version - Current version of that library.\n * @param variant - Bundle variant, e.g., node, rn, etc.\n *\n * @public\n */\nexport function registerVersion(\n libraryKeyOrName: string,\n version: string,\n variant?: string\n): void {\n // TODO: We can use this check to whitelist strings when/if we set up\n // a good whitelist system.\n let library = PLATFORM_LOG_STRING[libraryKeyOrName] ?? libraryKeyOrName;\n if (variant) {\n library += `-${variant}`;\n }\n const libraryMismatch = library.match(/\\s|\\//);\n const versionMismatch = version.match(/\\s|\\//);\n if (libraryMismatch || versionMismatch) {\n const warning = [\n `Unable to register library \"${library}\" with version \"${version}\":`\n ];\n if (libraryMismatch) {\n warning.push(\n `library name \"${library}\" contains illegal characters (whitespace or \"/\")`\n );\n }\n if (libraryMismatch && versionMismatch) {\n warning.push('and');\n }\n if (versionMismatch) {\n warning.push(\n `version name \"${version}\" contains illegal characters (whitespace or \"/\")`\n );\n }\n logger.warn(warning.join(' '));\n return;\n }\n _registerComponent(\n new Component(\n `${library}-version` as Name,\n () => ({ library, version }),\n ComponentType.VERSION\n )\n );\n}\n\n/**\n * Sets log handler for all Firebase SDKs.\n * @param logCallback - An optional custom log handler that executes user code whenever\n * the Firebase SDK makes a logging call.\n *\n * @public\n */\nexport function onLog(\n logCallback: LogCallback | null,\n options?: LogOptions\n): void {\n if (logCallback !== null && typeof logCallback !== 'function') {\n throw ERROR_FACTORY.create(AppError.INVALID_LOG_ARGUMENT);\n }\n setUserLogHandler(logCallback, options);\n}\n\n/**\n * Sets log level for all Firebase SDKs.\n *\n * All of the log types above the current log level are captured (i.e. if\n * you set the log level to `info`, errors are logged, but `debug` and\n * `verbose` logs are not).\n *\n * @public\n */\nexport function setLogLevel(logLevel: LogLevelString): void {\n setLogLevelImpl(logLevel);\n}\n", "/**\n * @license\n * Copyright 2021 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { FirebaseError } from '@firebase/util';\nimport { DBSchema, openDB, IDBPDatabase } from 'idb';\nimport { AppError, ERROR_FACTORY } from './errors';\nimport { FirebaseApp } from './public-types';\nimport { HeartbeatsInIndexedDB } from './types';\nimport { logger } from './logger';\n\nconst DB_NAME = 'firebase-heartbeat-database';\nconst DB_VERSION = 1;\nconst STORE_NAME = 'firebase-heartbeat-store';\n\ninterface AppDB extends DBSchema {\n 'firebase-heartbeat-store': {\n key: string;\n value: HeartbeatsInIndexedDB;\n };\n}\n\nlet dbPromise: Promise> | null = null;\nfunction getDbPromise(): Promise> {\n if (!dbPromise) {\n dbPromise = openDB(DB_NAME, DB_VERSION, {\n upgrade: (db, oldVersion) => {\n // We don't use 'break' in this switch statement, the fall-through\n // behavior is what we want, because if there are multiple versions between\n // the old version and the current version, we want ALL the migrations\n // that correspond to those versions to run, not only the last one.\n // eslint-disable-next-line default-case\n switch (oldVersion) {\n case 0:\n db.createObjectStore(STORE_NAME);\n }\n }\n }).catch(e => {\n throw ERROR_FACTORY.create(AppError.IDB_OPEN, {\n originalErrorMessage: e.message\n });\n });\n }\n return dbPromise;\n}\n\nexport async function readHeartbeatsFromIndexedDB(\n app: FirebaseApp\n): Promise {\n try {\n const db = await getDbPromise();\n return db\n .transaction(STORE_NAME)\n .objectStore(STORE_NAME)\n .get(computeKey(app)) as Promise;\n } catch (e) {\n if (e instanceof FirebaseError) {\n logger.warn(e.message);\n } else {\n const idbGetError = ERROR_FACTORY.create(AppError.IDB_GET, {\n originalErrorMessage: (e as Error)?.message\n });\n logger.warn(idbGetError.message);\n }\n }\n}\n\nexport async function writeHeartbeatsToIndexedDB(\n app: FirebaseApp,\n heartbeatObject: HeartbeatsInIndexedDB\n): Promise {\n try {\n const db = await getDbPromise();\n const tx = db.transaction(STORE_NAME, 'readwrite');\n const objectStore = tx.objectStore(STORE_NAME);\n await objectStore.put(heartbeatObject, computeKey(app));\n return tx.done;\n } catch (e) {\n if (e instanceof FirebaseError) {\n logger.warn(e.message);\n } else {\n const idbGetError = ERROR_FACTORY.create(AppError.IDB_WRITE, {\n originalErrorMessage: (e as Error)?.message\n });\n logger.warn(idbGetError.message);\n }\n }\n}\n\nfunction computeKey(app: FirebaseApp): string {\n return `${app.name}!${app.options.appId}`;\n}\n", "/**\n * @license\n * Copyright 2021 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ComponentContainer } from '@firebase/component';\nimport {\n base64urlEncodeWithoutPadding,\n isIndexedDBAvailable,\n validateIndexedDBOpenable\n} from '@firebase/util';\nimport {\n readHeartbeatsFromIndexedDB,\n writeHeartbeatsToIndexedDB\n} from './indexeddb';\nimport { FirebaseApp } from './public-types';\nimport {\n HeartbeatsByUserAgent,\n HeartbeatService,\n HeartbeatsInIndexedDB,\n HeartbeatStorage,\n SingleDateHeartbeat\n} from './types';\n\nconst MAX_HEADER_BYTES = 1024;\n// 30 days\nconst STORED_HEARTBEAT_RETENTION_MAX_MILLIS = 30 * 24 * 60 * 60 * 1000;\n\nexport class HeartbeatServiceImpl implements HeartbeatService {\n /**\n * The persistence layer for heartbeats\n * Leave public for easier testing.\n */\n _storage: HeartbeatStorageImpl;\n\n /**\n * In-memory cache for heartbeats, used by getHeartbeatsHeader() to generate\n * the header string.\n * Stores one record per date. This will be consolidated into the standard\n * format of one record per user agent string before being sent as a header.\n * Populated from indexedDB when the controller is instantiated and should\n * be kept in sync with indexedDB.\n * Leave public for easier testing.\n */\n _heartbeatsCache: HeartbeatsInIndexedDB | null = null;\n\n /**\n * the initialization promise for populating heartbeatCache.\n * If getHeartbeatsHeader() is called before the promise resolves\n * (hearbeatsCache == null), it should wait for this promise\n * Leave public for easier testing.\n */\n _heartbeatsCachePromise: Promise;\n constructor(private readonly container: ComponentContainer) {\n const app = this.container.getProvider('app').getImmediate();\n this._storage = new HeartbeatStorageImpl(app);\n this._heartbeatsCachePromise = this._storage.read().then(result => {\n this._heartbeatsCache = result;\n return result;\n });\n }\n\n /**\n * Called to report a heartbeat. The function will generate\n * a HeartbeatsByUserAgent object, update heartbeatsCache, and persist it\n * to IndexedDB.\n * Note that we only store one heartbeat per day. So if a heartbeat for today is\n * already logged, subsequent calls to this function in the same day will be ignored.\n */\n async triggerHeartbeat(): Promise {\n const platformLogger = this.container\n .getProvider('platform-logger')\n .getImmediate();\n\n // This is the \"Firebase user agent\" string from the platform logger\n // service, not the browser user agent.\n const agent = platformLogger.getPlatformInfoString();\n const date = getUTCDateString();\n if (this._heartbeatsCache === null) {\n this._heartbeatsCache = await this._heartbeatsCachePromise;\n }\n // Do not store a heartbeat if one is already stored for this day\n // or if a header has already been sent today.\n if (\n this._heartbeatsCache.lastSentHeartbeatDate === date ||\n this._heartbeatsCache.heartbeats.some(\n singleDateHeartbeat => singleDateHeartbeat.date === date\n )\n ) {\n return;\n } else {\n // There is no entry for this date. Create one.\n this._heartbeatsCache.heartbeats.push({ date, agent });\n }\n // Remove entries older than 30 days.\n this._heartbeatsCache.heartbeats = this._heartbeatsCache.heartbeats.filter(\n singleDateHeartbeat => {\n const hbTimestamp = new Date(singleDateHeartbeat.date).valueOf();\n const now = Date.now();\n return now - hbTimestamp <= STORED_HEARTBEAT_RETENTION_MAX_MILLIS;\n }\n );\n return this._storage.overwrite(this._heartbeatsCache);\n }\n\n /**\n * Returns a base64 encoded string which can be attached to the heartbeat-specific header directly.\n * It also clears all heartbeats from memory as well as in IndexedDB.\n *\n * NOTE: Consuming product SDKs should not send the header if this method\n * returns an empty string.\n */\n async getHeartbeatsHeader(): Promise {\n if (this._heartbeatsCache === null) {\n await this._heartbeatsCachePromise;\n }\n // If it's still null or the array is empty, there is no data to send.\n if (\n this._heartbeatsCache === null ||\n this._heartbeatsCache.heartbeats.length === 0\n ) {\n return '';\n }\n const date = getUTCDateString();\n // Extract as many heartbeats from the cache as will fit under the size limit.\n const { heartbeatsToSend, unsentEntries } = extractHeartbeatsForHeader(\n this._heartbeatsCache.heartbeats\n );\n const headerString = base64urlEncodeWithoutPadding(\n JSON.stringify({ version: 2, heartbeats: heartbeatsToSend })\n );\n // Store last sent date to prevent another being logged/sent for the same day.\n this._heartbeatsCache.lastSentHeartbeatDate = date;\n if (unsentEntries.length > 0) {\n // Store any unsent entries if they exist.\n this._heartbeatsCache.heartbeats = unsentEntries;\n // This seems more likely than emptying the array (below) to lead to some odd state\n // since the cache isn't empty and this will be called again on the next request,\n // and is probably safest if we await it.\n await this._storage.overwrite(this._heartbeatsCache);\n } else {\n this._heartbeatsCache.heartbeats = [];\n // Do not wait for this, to reduce latency.\n void this._storage.overwrite(this._heartbeatsCache);\n }\n return headerString;\n }\n}\n\nfunction getUTCDateString(): string {\n const today = new Date();\n // Returns date format 'YYYY-MM-DD'\n return today.toISOString().substring(0, 10);\n}\n\nexport function extractHeartbeatsForHeader(\n heartbeatsCache: SingleDateHeartbeat[],\n maxSize = MAX_HEADER_BYTES\n): {\n heartbeatsToSend: HeartbeatsByUserAgent[];\n unsentEntries: SingleDateHeartbeat[];\n} {\n // Heartbeats grouped by user agent in the standard format to be sent in\n // the header.\n const heartbeatsToSend: HeartbeatsByUserAgent[] = [];\n // Single date format heartbeats that are not sent.\n let unsentEntries = heartbeatsCache.slice();\n for (const singleDateHeartbeat of heartbeatsCache) {\n // Look for an existing entry with the same user agent.\n const heartbeatEntry = heartbeatsToSend.find(\n hb => hb.agent === singleDateHeartbeat.agent\n );\n if (!heartbeatEntry) {\n // If no entry for this user agent exists, create one.\n heartbeatsToSend.push({\n agent: singleDateHeartbeat.agent,\n dates: [singleDateHeartbeat.date]\n });\n if (countBytes(heartbeatsToSend) > maxSize) {\n // If the header would exceed max size, remove the added heartbeat\n // entry and stop adding to the header.\n heartbeatsToSend.pop();\n break;\n }\n } else {\n heartbeatEntry.dates.push(singleDateHeartbeat.date);\n // If the header would exceed max size, remove the added date\n // and stop adding to the header.\n if (countBytes(heartbeatsToSend) > maxSize) {\n heartbeatEntry.dates.pop();\n break;\n }\n }\n // Pop unsent entry from queue. (Skipped if adding the entry exceeded\n // quota and the loop breaks early.)\n unsentEntries = unsentEntries.slice(1);\n }\n return {\n heartbeatsToSend,\n unsentEntries\n };\n}\n\nexport class HeartbeatStorageImpl implements HeartbeatStorage {\n private _canUseIndexedDBPromise: Promise;\n constructor(public app: FirebaseApp) {\n this._canUseIndexedDBPromise = this.runIndexedDBEnvironmentCheck();\n }\n async runIndexedDBEnvironmentCheck(): Promise {\n if (!isIndexedDBAvailable()) {\n return false;\n } else {\n return validateIndexedDBOpenable()\n .then(() => true)\n .catch(() => false);\n }\n }\n /**\n * Read all heartbeats.\n */\n async read(): Promise {\n const canUseIndexedDB = await this._canUseIndexedDBPromise;\n if (!canUseIndexedDB) {\n return { heartbeats: [] };\n } else {\n const idbHeartbeatObject = await readHeartbeatsFromIndexedDB(this.app);\n return idbHeartbeatObject || { heartbeats: [] };\n }\n }\n // overwrite the storage with the provided heartbeats\n async overwrite(heartbeatsObject: HeartbeatsInIndexedDB): Promise {\n const canUseIndexedDB = await this._canUseIndexedDBPromise;\n if (!canUseIndexedDB) {\n return;\n } else {\n const existingHeartbeatsObject = await this.read();\n return writeHeartbeatsToIndexedDB(this.app, {\n lastSentHeartbeatDate:\n heartbeatsObject.lastSentHeartbeatDate ??\n existingHeartbeatsObject.lastSentHeartbeatDate,\n heartbeats: heartbeatsObject.heartbeats\n });\n }\n }\n // add heartbeats\n async add(heartbeatsObject: HeartbeatsInIndexedDB): Promise {\n const canUseIndexedDB = await this._canUseIndexedDBPromise;\n if (!canUseIndexedDB) {\n return;\n } else {\n const existingHeartbeatsObject = await this.read();\n return writeHeartbeatsToIndexedDB(this.app, {\n lastSentHeartbeatDate:\n heartbeatsObject.lastSentHeartbeatDate ??\n existingHeartbeatsObject.lastSentHeartbeatDate,\n heartbeats: [\n ...existingHeartbeatsObject.heartbeats,\n ...heartbeatsObject.heartbeats\n ]\n });\n }\n }\n}\n\n/**\n * Calculate bytes of a HeartbeatsByUserAgent array after being wrapped\n * in a platform logging header JSON object, stringified, and converted\n * to base 64.\n */\nexport function countBytes(heartbeatsCache: HeartbeatsByUserAgent[]): number {\n // base64 has a restricted set of characters, all of which should be 1 byte.\n return base64urlEncodeWithoutPadding(\n // heartbeatsCache wrapper properties\n JSON.stringify({ version: 2, heartbeats: heartbeatsCache })\n ).length;\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Component, ComponentType } from '@firebase/component';\nimport { PlatformLoggerServiceImpl } from './platformLoggerService';\nimport { name, version } from '../package.json';\nimport { _registerComponent } from './internal';\nimport { registerVersion } from './api';\nimport { HeartbeatServiceImpl } from './heartbeatService';\n\nexport function registerCoreComponents(variant?: string): void {\n _registerComponent(\n new Component(\n 'platform-logger',\n container => new PlatformLoggerServiceImpl(container),\n ComponentType.PRIVATE\n )\n );\n _registerComponent(\n new Component(\n 'heartbeat',\n container => new HeartbeatServiceImpl(container),\n ComponentType.PRIVATE\n )\n );\n\n // Register `app` package.\n registerVersion(name, version, variant);\n // BUILD_TARGET will be replaced by values like esm5, esm2017, cjs5, etc during the compilation\n registerVersion(name, version, '__BUILD_TARGET__');\n // Register platform SDK identifier (no version).\n registerVersion('fire-js', '');\n}\n", "/**\n * Firebase App\n *\n * @remarks This package coordinates the communication between the different Firebase components\n * @packageDocumentation\n */\n\n/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { registerCoreComponents } from './registerCoreComponents';\n\nexport * from './api';\nexport * from './internal';\nexport * from './public-types';\n\nregisterCoreComponents('__RUNTIME_ENV__');\n", "/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { registerVersion } from '@firebase/app';\nimport { name, version } from '../package.json';\n\nregisterVersion(name, version, 'app');\nexport * from '@firebase/app';\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { version } from '../../package.json';\n\nexport const PENDING_TIMEOUT_MS = 10000;\n\nexport const PACKAGE_VERSION = `w:${version}`;\nexport const INTERNAL_AUTH_VERSION = 'FIS_v2';\n\nexport const INSTALLATIONS_API_URL =\n 'https://firebaseinstallations.googleapis.com/v1';\n\nexport const TOKEN_EXPIRATION_BUFFER = 60 * 60 * 1000; // One hour\n\nexport const SERVICE = 'installations';\nexport const SERVICE_NAME = 'Installations';\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ErrorFactory, FirebaseError } from '@firebase/util';\nimport { SERVICE, SERVICE_NAME } from './constants';\n\nexport const enum ErrorCode {\n MISSING_APP_CONFIG_VALUES = 'missing-app-config-values',\n NOT_REGISTERED = 'not-registered',\n INSTALLATION_NOT_FOUND = 'installation-not-found',\n REQUEST_FAILED = 'request-failed',\n APP_OFFLINE = 'app-offline',\n DELETE_PENDING_REGISTRATION = 'delete-pending-registration'\n}\n\nconst ERROR_DESCRIPTION_MAP: { readonly [key in ErrorCode]: string } = {\n [ErrorCode.MISSING_APP_CONFIG_VALUES]:\n 'Missing App configuration value: \"{$valueName}\"',\n [ErrorCode.NOT_REGISTERED]: 'Firebase Installation is not registered.',\n [ErrorCode.INSTALLATION_NOT_FOUND]: 'Firebase Installation not found.',\n [ErrorCode.REQUEST_FAILED]:\n '{$requestName} request failed with error \"{$serverCode} {$serverStatus}: {$serverMessage}\"',\n [ErrorCode.APP_OFFLINE]: 'Could not process request. Application offline.',\n [ErrorCode.DELETE_PENDING_REGISTRATION]:\n \"Can't delete installation while there is a pending registration request.\"\n};\n\ninterface ErrorParams {\n [ErrorCode.MISSING_APP_CONFIG_VALUES]: {\n valueName: string;\n };\n [ErrorCode.REQUEST_FAILED]: {\n requestName: string;\n [index: string]: string | number; // to make Typescript 3.8 happy\n } & ServerErrorData;\n}\n\nexport const ERROR_FACTORY = new ErrorFactory(\n SERVICE,\n SERVICE_NAME,\n ERROR_DESCRIPTION_MAP\n);\n\nexport interface ServerErrorData {\n serverCode: number;\n serverMessage: string;\n serverStatus: string;\n}\n\nexport type ServerError = FirebaseError & { customData: ServerErrorData };\n\n/** Returns true if error is a FirebaseError that is based on an error from the server. */\nexport function isServerError(error: unknown): error is ServerError {\n return (\n error instanceof FirebaseError &&\n error.code.includes(ErrorCode.REQUEST_FAILED)\n );\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { FirebaseError } from '@firebase/util';\nimport { GenerateAuthTokenResponse } from '../interfaces/api-response';\nimport {\n CompletedAuthToken,\n RegisteredInstallationEntry,\n RequestStatus\n} from '../interfaces/installation-entry';\nimport {\n INSTALLATIONS_API_URL,\n INTERNAL_AUTH_VERSION\n} from '../util/constants';\nimport { ERROR_FACTORY, ErrorCode } from '../util/errors';\nimport { AppConfig } from '../interfaces/installation-impl';\n\nexport function getInstallationsEndpoint({ projectId }: AppConfig): string {\n return `${INSTALLATIONS_API_URL}/projects/${projectId}/installations`;\n}\n\nexport function extractAuthTokenInfoFromResponse(\n response: GenerateAuthTokenResponse\n): CompletedAuthToken {\n return {\n token: response.token,\n requestStatus: RequestStatus.COMPLETED,\n expiresIn: getExpiresInFromResponseExpiresIn(response.expiresIn),\n creationTime: Date.now()\n };\n}\n\nexport async function getErrorFromResponse(\n requestName: string,\n response: Response\n): Promise {\n const responseJson: ErrorResponse = await response.json();\n const errorData = responseJson.error;\n return ERROR_FACTORY.create(ErrorCode.REQUEST_FAILED, {\n requestName,\n serverCode: errorData.code,\n serverMessage: errorData.message,\n serverStatus: errorData.status\n });\n}\n\nexport function getHeaders({ apiKey }: AppConfig): Headers {\n return new Headers({\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n 'x-goog-api-key': apiKey\n });\n}\n\nexport function getHeadersWithAuth(\n appConfig: AppConfig,\n { refreshToken }: RegisteredInstallationEntry\n): Headers {\n const headers = getHeaders(appConfig);\n headers.append('Authorization', getAuthorizationHeader(refreshToken));\n return headers;\n}\n\nexport interface ErrorResponse {\n error: {\n code: number;\n message: string;\n status: string;\n };\n}\n\n/**\n * Calls the passed in fetch wrapper and returns the response.\n * If the returned response has a status of 5xx, re-runs the function once and\n * returns the response.\n */\nexport async function retryIfServerError(\n fn: () => Promise\n): Promise {\n const result = await fn();\n\n if (result.status >= 500 && result.status < 600) {\n // Internal Server Error. Retry request.\n return fn();\n }\n\n return result;\n}\n\nfunction getExpiresInFromResponseExpiresIn(responseExpiresIn: string): number {\n // This works because the server will never respond with fractions of a second.\n return Number(responseExpiresIn.replace('s', '000'));\n}\n\nfunction getAuthorizationHeader(refreshToken: string): string {\n return `${INTERNAL_AUTH_VERSION} ${refreshToken}`;\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { CreateInstallationResponse } from '../interfaces/api-response';\nimport {\n InProgressInstallationEntry,\n RegisteredInstallationEntry,\n RequestStatus\n} from '../interfaces/installation-entry';\nimport { INTERNAL_AUTH_VERSION, PACKAGE_VERSION } from '../util/constants';\nimport {\n extractAuthTokenInfoFromResponse,\n getErrorFromResponse,\n getHeaders,\n getInstallationsEndpoint,\n retryIfServerError\n} from './common';\nimport { FirebaseInstallationsImpl } from '../interfaces/installation-impl';\n\nexport async function createInstallationRequest(\n { appConfig, heartbeatServiceProvider }: FirebaseInstallationsImpl,\n { fid }: InProgressInstallationEntry\n): Promise {\n const endpoint = getInstallationsEndpoint(appConfig);\n\n const headers = getHeaders(appConfig);\n\n // If heartbeat service exists, add the heartbeat string to the header.\n const heartbeatService = heartbeatServiceProvider.getImmediate({\n optional: true\n });\n if (heartbeatService) {\n const heartbeatsHeader = await heartbeatService.getHeartbeatsHeader();\n if (heartbeatsHeader) {\n headers.append('x-firebase-client', heartbeatsHeader);\n }\n }\n\n const body = {\n fid,\n authVersion: INTERNAL_AUTH_VERSION,\n appId: appConfig.appId,\n sdkVersion: PACKAGE_VERSION\n };\n\n const request: RequestInit = {\n method: 'POST',\n headers,\n body: JSON.stringify(body)\n };\n\n const response = await retryIfServerError(() => fetch(endpoint, request));\n if (response.ok) {\n const responseValue: CreateInstallationResponse = await response.json();\n const registeredInstallationEntry: RegisteredInstallationEntry = {\n fid: responseValue.fid || fid,\n registrationStatus: RequestStatus.COMPLETED,\n refreshToken: responseValue.refreshToken,\n authToken: extractAuthTokenInfoFromResponse(responseValue.authToken)\n };\n return registeredInstallationEntry;\n } else {\n throw await getErrorFromResponse('Create Installation', response);\n }\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/** Returns a promise that resolves after given time passes. */\nexport function sleep(ms: number): Promise {\n return new Promise(resolve => {\n setTimeout(resolve, ms);\n });\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport function bufferToBase64UrlSafe(array: Uint8Array): string {\n const b64 = btoa(String.fromCharCode(...array));\n return b64.replace(/\\+/g, '-').replace(/\\//g, '_');\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { bufferToBase64UrlSafe } from './buffer-to-base64-url-safe';\n\nexport const VALID_FID_PATTERN = /^[cdef][\\w-]{21}$/;\nexport const INVALID_FID = '';\n\n/**\n * Generates a new FID using random values from Web Crypto API.\n * Returns an empty string if FID generation fails for any reason.\n */\nexport function generateFid(): string {\n try {\n // A valid FID has exactly 22 base64 characters, which is 132 bits, or 16.5\n // bytes. our implementation generates a 17 byte array instead.\n const fidByteArray = new Uint8Array(17);\n const crypto =\n self.crypto || (self as unknown as { msCrypto: Crypto }).msCrypto;\n crypto.getRandomValues(fidByteArray);\n\n // Replace the first 4 random bits with the constant FID header of 0b0111.\n fidByteArray[0] = 0b01110000 + (fidByteArray[0] % 0b00010000);\n\n const fid = encode(fidByteArray);\n\n return VALID_FID_PATTERN.test(fid) ? fid : INVALID_FID;\n } catch {\n // FID generation errored\n return INVALID_FID;\n }\n}\n\n/** Converts a FID Uint8Array to a base64 string representation. */\nfunction encode(fidByteArray: Uint8Array): string {\n const b64String = bufferToBase64UrlSafe(fidByteArray);\n\n // Remove the 23rd character that was added because of the extra 4 bits at the\n // end of our 17 byte array, and the '=' padding.\n return b64String.substr(0, 22);\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { AppConfig } from '../interfaces/installation-impl';\n\n/** Returns a string key that can be used to identify the app. */\nexport function getKey(appConfig: AppConfig): string {\n return `${appConfig.appName}!${appConfig.appId}`;\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { getKey } from '../util/get-key';\nimport { AppConfig } from '../interfaces/installation-impl';\nimport { IdChangeCallbackFn } from '../api';\n\nconst fidChangeCallbacks: Map> = new Map();\n\n/**\n * Calls the onIdChange callbacks with the new FID value, and broadcasts the\n * change to other tabs.\n */\nexport function fidChanged(appConfig: AppConfig, fid: string): void {\n const key = getKey(appConfig);\n\n callFidChangeCallbacks(key, fid);\n broadcastFidChange(key, fid);\n}\n\nexport function addCallback(\n appConfig: AppConfig,\n callback: IdChangeCallbackFn\n): void {\n // Open the broadcast channel if it's not already open,\n // to be able to listen to change events from other tabs.\n getBroadcastChannel();\n\n const key = getKey(appConfig);\n\n let callbackSet = fidChangeCallbacks.get(key);\n if (!callbackSet) {\n callbackSet = new Set();\n fidChangeCallbacks.set(key, callbackSet);\n }\n callbackSet.add(callback);\n}\n\nexport function removeCallback(\n appConfig: AppConfig,\n callback: IdChangeCallbackFn\n): void {\n const key = getKey(appConfig);\n\n const callbackSet = fidChangeCallbacks.get(key);\n\n if (!callbackSet) {\n return;\n }\n\n callbackSet.delete(callback);\n if (callbackSet.size === 0) {\n fidChangeCallbacks.delete(key);\n }\n\n // Close broadcast channel if there are no more callbacks.\n closeBroadcastChannel();\n}\n\nfunction callFidChangeCallbacks(key: string, fid: string): void {\n const callbacks = fidChangeCallbacks.get(key);\n if (!callbacks) {\n return;\n }\n\n for (const callback of callbacks) {\n callback(fid);\n }\n}\n\nfunction broadcastFidChange(key: string, fid: string): void {\n const channel = getBroadcastChannel();\n if (channel) {\n channel.postMessage({ key, fid });\n }\n closeBroadcastChannel();\n}\n\nlet broadcastChannel: BroadcastChannel | null = null;\n/** Opens and returns a BroadcastChannel if it is supported by the browser. */\nfunction getBroadcastChannel(): BroadcastChannel | null {\n if (!broadcastChannel && 'BroadcastChannel' in self) {\n broadcastChannel = new BroadcastChannel('[Firebase] FID Change');\n broadcastChannel.onmessage = e => {\n callFidChangeCallbacks(e.data.key, e.data.fid);\n };\n }\n return broadcastChannel;\n}\n\nfunction closeBroadcastChannel(): void {\n if (fidChangeCallbacks.size === 0 && broadcastChannel) {\n broadcastChannel.close();\n broadcastChannel = null;\n }\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { DBSchema, IDBPDatabase, openDB } from 'idb';\nimport { AppConfig } from '../interfaces/installation-impl';\nimport { InstallationEntry } from '../interfaces/installation-entry';\nimport { getKey } from '../util/get-key';\nimport { fidChanged } from './fid-changed';\n\nconst DATABASE_NAME = 'firebase-installations-database';\nconst DATABASE_VERSION = 1;\nconst OBJECT_STORE_NAME = 'firebase-installations-store';\n\ninterface InstallationsDB extends DBSchema {\n 'firebase-installations-store': {\n key: string;\n value: InstallationEntry | undefined;\n };\n}\n\nlet dbPromise: Promise> | null = null;\nfunction getDbPromise(): Promise> {\n if (!dbPromise) {\n dbPromise = openDB(DATABASE_NAME, DATABASE_VERSION, {\n upgrade: (db, oldVersion) => {\n // We don't use 'break' in this switch statement, the fall-through\n // behavior is what we want, because if there are multiple versions between\n // the old version and the current version, we want ALL the migrations\n // that correspond to those versions to run, not only the last one.\n // eslint-disable-next-line default-case\n switch (oldVersion) {\n case 0:\n db.createObjectStore(OBJECT_STORE_NAME);\n }\n }\n });\n }\n return dbPromise;\n}\n\n/** Gets record(s) from the objectStore that match the given key. */\nexport async function get(\n appConfig: AppConfig\n): Promise {\n const key = getKey(appConfig);\n const db = await getDbPromise();\n return db\n .transaction(OBJECT_STORE_NAME)\n .objectStore(OBJECT_STORE_NAME)\n .get(key) as Promise;\n}\n\n/** Assigns or overwrites the record for the given key with the given value. */\nexport async function set(\n appConfig: AppConfig,\n value: ValueType\n): Promise {\n const key = getKey(appConfig);\n const db = await getDbPromise();\n const tx = db.transaction(OBJECT_STORE_NAME, 'readwrite');\n const objectStore = tx.objectStore(OBJECT_STORE_NAME);\n const oldValue = (await objectStore.get(key)) as InstallationEntry;\n await objectStore.put(value, key);\n await tx.done;\n\n if (!oldValue || oldValue.fid !== value.fid) {\n fidChanged(appConfig, value.fid);\n }\n\n return value;\n}\n\n/** Removes record(s) from the objectStore that match the given key. */\nexport async function remove(appConfig: AppConfig): Promise {\n const key = getKey(appConfig);\n const db = await getDbPromise();\n const tx = db.transaction(OBJECT_STORE_NAME, 'readwrite');\n await tx.objectStore(OBJECT_STORE_NAME).delete(key);\n await tx.done;\n}\n\n/**\n * Atomically updates a record with the result of updateFn, which gets\n * called with the current value. If newValue is undefined, the record is\n * deleted instead.\n * @return Updated value\n */\nexport async function update(\n appConfig: AppConfig,\n updateFn: (previousValue: InstallationEntry | undefined) => ValueType\n): Promise {\n const key = getKey(appConfig);\n const db = await getDbPromise();\n const tx = db.transaction(OBJECT_STORE_NAME, 'readwrite');\n const store = tx.objectStore(OBJECT_STORE_NAME);\n const oldValue: InstallationEntry | undefined = (await store.get(\n key\n )) as InstallationEntry;\n const newValue = updateFn(oldValue);\n\n if (newValue === undefined) {\n await store.delete(key);\n } else {\n await store.put(newValue, key);\n }\n await tx.done;\n\n if (newValue && (!oldValue || oldValue.fid !== newValue.fid)) {\n fidChanged(appConfig, newValue.fid);\n }\n\n return newValue;\n}\n\nexport async function clear(): Promise {\n const db = await getDbPromise();\n const tx = db.transaction(OBJECT_STORE_NAME, 'readwrite');\n await tx.objectStore(OBJECT_STORE_NAME).clear();\n await tx.done;\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { createInstallationRequest } from '../functions/create-installation-request';\nimport {\n AppConfig,\n FirebaseInstallationsImpl\n} from '../interfaces/installation-impl';\nimport {\n InProgressInstallationEntry,\n InstallationEntry,\n RegisteredInstallationEntry,\n RequestStatus\n} from '../interfaces/installation-entry';\nimport { PENDING_TIMEOUT_MS } from '../util/constants';\nimport { ERROR_FACTORY, ErrorCode, isServerError } from '../util/errors';\nimport { sleep } from '../util/sleep';\nimport { generateFid, INVALID_FID } from './generate-fid';\nimport { remove, set, update } from './idb-manager';\n\nexport interface InstallationEntryWithRegistrationPromise {\n installationEntry: InstallationEntry;\n /** Exist iff the installationEntry is not registered. */\n registrationPromise?: Promise;\n}\n\n/**\n * Updates and returns the InstallationEntry from the database.\n * Also triggers a registration request if it is necessary and possible.\n */\nexport async function getInstallationEntry(\n installations: FirebaseInstallationsImpl\n): Promise {\n let registrationPromise: Promise | undefined;\n\n const installationEntry = await update(installations.appConfig, oldEntry => {\n const installationEntry = updateOrCreateInstallationEntry(oldEntry);\n const entryWithPromise = triggerRegistrationIfNecessary(\n installations,\n installationEntry\n );\n registrationPromise = entryWithPromise.registrationPromise;\n return entryWithPromise.installationEntry;\n });\n\n if (installationEntry.fid === INVALID_FID) {\n // FID generation failed. Waiting for the FID from the server.\n return { installationEntry: await registrationPromise! };\n }\n\n return {\n installationEntry,\n registrationPromise\n };\n}\n\n/**\n * Creates a new Installation Entry if one does not exist.\n * Also clears timed out pending requests.\n */\nfunction updateOrCreateInstallationEntry(\n oldEntry: InstallationEntry | undefined\n): InstallationEntry {\n const entry: InstallationEntry = oldEntry || {\n fid: generateFid(),\n registrationStatus: RequestStatus.NOT_STARTED\n };\n\n return clearTimedOutRequest(entry);\n}\n\n/**\n * If the Firebase Installation is not registered yet, this will trigger the\n * registration and return an InProgressInstallationEntry.\n *\n * If registrationPromise does not exist, the installationEntry is guaranteed\n * to be registered.\n */\nfunction triggerRegistrationIfNecessary(\n installations: FirebaseInstallationsImpl,\n installationEntry: InstallationEntry\n): InstallationEntryWithRegistrationPromise {\n if (installationEntry.registrationStatus === RequestStatus.NOT_STARTED) {\n if (!navigator.onLine) {\n // Registration required but app is offline.\n const registrationPromiseWithError = Promise.reject(\n ERROR_FACTORY.create(ErrorCode.APP_OFFLINE)\n );\n return {\n installationEntry,\n registrationPromise: registrationPromiseWithError\n };\n }\n\n // Try registering. Change status to IN_PROGRESS.\n const inProgressEntry: InProgressInstallationEntry = {\n fid: installationEntry.fid,\n registrationStatus: RequestStatus.IN_PROGRESS,\n registrationTime: Date.now()\n };\n const registrationPromise = registerInstallation(\n installations,\n inProgressEntry\n );\n return { installationEntry: inProgressEntry, registrationPromise };\n } else if (\n installationEntry.registrationStatus === RequestStatus.IN_PROGRESS\n ) {\n return {\n installationEntry,\n registrationPromise: waitUntilFidRegistration(installations)\n };\n } else {\n return { installationEntry };\n }\n}\n\n/** This will be executed only once for each new Firebase Installation. */\nasync function registerInstallation(\n installations: FirebaseInstallationsImpl,\n installationEntry: InProgressInstallationEntry\n): Promise {\n try {\n const registeredInstallationEntry = await createInstallationRequest(\n installations,\n installationEntry\n );\n return set(installations.appConfig, registeredInstallationEntry);\n } catch (e) {\n if (isServerError(e) && e.customData.serverCode === 409) {\n // Server returned a \"FID can not be used\" error.\n // Generate a new ID next time.\n await remove(installations.appConfig);\n } else {\n // Registration failed. Set FID as not registered.\n await set(installations.appConfig, {\n fid: installationEntry.fid,\n registrationStatus: RequestStatus.NOT_STARTED\n });\n }\n throw e;\n }\n}\n\n/** Call if FID registration is pending in another request. */\nasync function waitUntilFidRegistration(\n installations: FirebaseInstallationsImpl\n): Promise {\n // Unfortunately, there is no way of reliably observing when a value in\n // IndexedDB changes (yet, see https://github.com/WICG/indexed-db-observers),\n // so we need to poll.\n\n let entry: InstallationEntry = await updateInstallationRequest(\n installations.appConfig\n );\n while (entry.registrationStatus === RequestStatus.IN_PROGRESS) {\n // createInstallation request still in progress.\n await sleep(100);\n\n entry = await updateInstallationRequest(installations.appConfig);\n }\n\n if (entry.registrationStatus === RequestStatus.NOT_STARTED) {\n // The request timed out or failed in a different call. Try again.\n const { installationEntry, registrationPromise } =\n await getInstallationEntry(installations);\n\n if (registrationPromise) {\n return registrationPromise;\n } else {\n // if there is no registrationPromise, entry is registered.\n return installationEntry as RegisteredInstallationEntry;\n }\n }\n\n return entry;\n}\n\n/**\n * Called only if there is a CreateInstallation request in progress.\n *\n * Updates the InstallationEntry in the DB based on the status of the\n * CreateInstallation request.\n *\n * Returns the updated InstallationEntry.\n */\nfunction updateInstallationRequest(\n appConfig: AppConfig\n): Promise {\n return update(appConfig, oldEntry => {\n if (!oldEntry) {\n throw ERROR_FACTORY.create(ErrorCode.INSTALLATION_NOT_FOUND);\n }\n return clearTimedOutRequest(oldEntry);\n });\n}\n\nfunction clearTimedOutRequest(entry: InstallationEntry): InstallationEntry {\n if (hasInstallationRequestTimedOut(entry)) {\n return {\n fid: entry.fid,\n registrationStatus: RequestStatus.NOT_STARTED\n };\n }\n\n return entry;\n}\n\nfunction hasInstallationRequestTimedOut(\n installationEntry: InstallationEntry\n): boolean {\n return (\n installationEntry.registrationStatus === RequestStatus.IN_PROGRESS &&\n installationEntry.registrationTime + PENDING_TIMEOUT_MS < Date.now()\n );\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { GenerateAuthTokenResponse } from '../interfaces/api-response';\nimport {\n CompletedAuthToken,\n RegisteredInstallationEntry\n} from '../interfaces/installation-entry';\nimport { PACKAGE_VERSION } from '../util/constants';\nimport {\n extractAuthTokenInfoFromResponse,\n getErrorFromResponse,\n getHeadersWithAuth,\n getInstallationsEndpoint,\n retryIfServerError\n} from './common';\nimport {\n FirebaseInstallationsImpl,\n AppConfig\n} from '../interfaces/installation-impl';\n\nexport async function generateAuthTokenRequest(\n { appConfig, heartbeatServiceProvider }: FirebaseInstallationsImpl,\n installationEntry: RegisteredInstallationEntry\n): Promise {\n const endpoint = getGenerateAuthTokenEndpoint(appConfig, installationEntry);\n\n const headers = getHeadersWithAuth(appConfig, installationEntry);\n\n // If heartbeat service exists, add the heartbeat string to the header.\n const heartbeatService = heartbeatServiceProvider.getImmediate({\n optional: true\n });\n if (heartbeatService) {\n const heartbeatsHeader = await heartbeatService.getHeartbeatsHeader();\n if (heartbeatsHeader) {\n headers.append('x-firebase-client', heartbeatsHeader);\n }\n }\n\n const body = {\n installation: {\n sdkVersion: PACKAGE_VERSION,\n appId: appConfig.appId\n }\n };\n\n const request: RequestInit = {\n method: 'POST',\n headers,\n body: JSON.stringify(body)\n };\n\n const response = await retryIfServerError(() => fetch(endpoint, request));\n if (response.ok) {\n const responseValue: GenerateAuthTokenResponse = await response.json();\n const completedAuthToken: CompletedAuthToken =\n extractAuthTokenInfoFromResponse(responseValue);\n return completedAuthToken;\n } else {\n throw await getErrorFromResponse('Generate Auth Token', response);\n }\n}\n\nfunction getGenerateAuthTokenEndpoint(\n appConfig: AppConfig,\n { fid }: RegisteredInstallationEntry\n): string {\n return `${getInstallationsEndpoint(appConfig)}/${fid}/authTokens:generate`;\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { generateAuthTokenRequest } from '../functions/generate-auth-token-request';\nimport {\n AppConfig,\n FirebaseInstallationsImpl\n} from '../interfaces/installation-impl';\nimport {\n AuthToken,\n CompletedAuthToken,\n InProgressAuthToken,\n InstallationEntry,\n RegisteredInstallationEntry,\n RequestStatus\n} from '../interfaces/installation-entry';\nimport { PENDING_TIMEOUT_MS, TOKEN_EXPIRATION_BUFFER } from '../util/constants';\nimport { ERROR_FACTORY, ErrorCode, isServerError } from '../util/errors';\nimport { sleep } from '../util/sleep';\nimport { remove, set, update } from './idb-manager';\n\n/**\n * Returns a valid authentication token for the installation. Generates a new\n * token if one doesn't exist, is expired or about to expire.\n *\n * Should only be called if the Firebase Installation is registered.\n */\nexport async function refreshAuthToken(\n installations: FirebaseInstallationsImpl,\n forceRefresh = false\n): Promise {\n let tokenPromise: Promise | undefined;\n const entry = await update(installations.appConfig, oldEntry => {\n if (!isEntryRegistered(oldEntry)) {\n throw ERROR_FACTORY.create(ErrorCode.NOT_REGISTERED);\n }\n\n const oldAuthToken = oldEntry.authToken;\n if (!forceRefresh && isAuthTokenValid(oldAuthToken)) {\n // There is a valid token in the DB.\n return oldEntry;\n } else if (oldAuthToken.requestStatus === RequestStatus.IN_PROGRESS) {\n // There already is a token request in progress.\n tokenPromise = waitUntilAuthTokenRequest(installations, forceRefresh);\n return oldEntry;\n } else {\n // No token or token expired.\n if (!navigator.onLine) {\n throw ERROR_FACTORY.create(ErrorCode.APP_OFFLINE);\n }\n\n const inProgressEntry = makeAuthTokenRequestInProgressEntry(oldEntry);\n tokenPromise = fetchAuthTokenFromServer(installations, inProgressEntry);\n return inProgressEntry;\n }\n });\n\n const authToken = tokenPromise\n ? await tokenPromise\n : (entry.authToken as CompletedAuthToken);\n return authToken;\n}\n\n/**\n * Call only if FID is registered and Auth Token request is in progress.\n *\n * Waits until the current pending request finishes. If the request times out,\n * tries once in this thread as well.\n */\nasync function waitUntilAuthTokenRequest(\n installations: FirebaseInstallationsImpl,\n forceRefresh: boolean\n): Promise {\n // Unfortunately, there is no way of reliably observing when a value in\n // IndexedDB changes (yet, see https://github.com/WICG/indexed-db-observers),\n // so we need to poll.\n\n let entry = await updateAuthTokenRequest(installations.appConfig);\n while (entry.authToken.requestStatus === RequestStatus.IN_PROGRESS) {\n // generateAuthToken still in progress.\n await sleep(100);\n\n entry = await updateAuthTokenRequest(installations.appConfig);\n }\n\n const authToken = entry.authToken;\n if (authToken.requestStatus === RequestStatus.NOT_STARTED) {\n // The request timed out or failed in a different call. Try again.\n return refreshAuthToken(installations, forceRefresh);\n } else {\n return authToken;\n }\n}\n\n/**\n * Called only if there is a GenerateAuthToken request in progress.\n *\n * Updates the InstallationEntry in the DB based on the status of the\n * GenerateAuthToken request.\n *\n * Returns the updated InstallationEntry.\n */\nfunction updateAuthTokenRequest(\n appConfig: AppConfig\n): Promise {\n return update(appConfig, oldEntry => {\n if (!isEntryRegistered(oldEntry)) {\n throw ERROR_FACTORY.create(ErrorCode.NOT_REGISTERED);\n }\n\n const oldAuthToken = oldEntry.authToken;\n if (hasAuthTokenRequestTimedOut(oldAuthToken)) {\n return {\n ...oldEntry,\n authToken: { requestStatus: RequestStatus.NOT_STARTED }\n };\n }\n\n return oldEntry;\n });\n}\n\nasync function fetchAuthTokenFromServer(\n installations: FirebaseInstallationsImpl,\n installationEntry: RegisteredInstallationEntry\n): Promise {\n try {\n const authToken = await generateAuthTokenRequest(\n installations,\n installationEntry\n );\n const updatedInstallationEntry: RegisteredInstallationEntry = {\n ...installationEntry,\n authToken\n };\n await set(installations.appConfig, updatedInstallationEntry);\n return authToken;\n } catch (e) {\n if (\n isServerError(e) &&\n (e.customData.serverCode === 401 || e.customData.serverCode === 404)\n ) {\n // Server returned a \"FID not found\" or a \"Invalid authentication\" error.\n // Generate a new ID next time.\n await remove(installations.appConfig);\n } else {\n const updatedInstallationEntry: RegisteredInstallationEntry = {\n ...installationEntry,\n authToken: { requestStatus: RequestStatus.NOT_STARTED }\n };\n await set(installations.appConfig, updatedInstallationEntry);\n }\n throw e;\n }\n}\n\nfunction isEntryRegistered(\n installationEntry: InstallationEntry | undefined\n): installationEntry is RegisteredInstallationEntry {\n return (\n installationEntry !== undefined &&\n installationEntry.registrationStatus === RequestStatus.COMPLETED\n );\n}\n\nfunction isAuthTokenValid(authToken: AuthToken): boolean {\n return (\n authToken.requestStatus === RequestStatus.COMPLETED &&\n !isAuthTokenExpired(authToken)\n );\n}\n\nfunction isAuthTokenExpired(authToken: CompletedAuthToken): boolean {\n const now = Date.now();\n return (\n now < authToken.creationTime ||\n authToken.creationTime + authToken.expiresIn < now + TOKEN_EXPIRATION_BUFFER\n );\n}\n\n/** Returns an updated InstallationEntry with an InProgressAuthToken. */\nfunction makeAuthTokenRequestInProgressEntry(\n oldEntry: RegisteredInstallationEntry\n): RegisteredInstallationEntry {\n const inProgressAuthToken: InProgressAuthToken = {\n requestStatus: RequestStatus.IN_PROGRESS,\n requestTime: Date.now()\n };\n return {\n ...oldEntry,\n authToken: inProgressAuthToken\n };\n}\n\nfunction hasAuthTokenRequestTimedOut(authToken: AuthToken): boolean {\n return (\n authToken.requestStatus === RequestStatus.IN_PROGRESS &&\n authToken.requestTime + PENDING_TIMEOUT_MS < Date.now()\n );\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { getInstallationEntry } from '../helpers/get-installation-entry';\nimport { refreshAuthToken } from '../helpers/refresh-auth-token';\nimport { FirebaseInstallationsImpl } from '../interfaces/installation-impl';\nimport { Installations } from '../interfaces/public-types';\n\n/**\n * Creates a Firebase Installation if there isn't one for the app and\n * returns the Installation ID.\n * @param installations - The `Installations` instance.\n *\n * @public\n */\nexport async function getId(installations: Installations): Promise {\n const installationsImpl = installations as FirebaseInstallationsImpl;\n const { installationEntry, registrationPromise } = await getInstallationEntry(\n installationsImpl\n );\n\n if (registrationPromise) {\n registrationPromise.catch(console.error);\n } else {\n // If the installation is already registered, update the authentication\n // token if needed.\n refreshAuthToken(installationsImpl).catch(console.error);\n }\n\n return installationEntry.fid;\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { getInstallationEntry } from '../helpers/get-installation-entry';\nimport { refreshAuthToken } from '../helpers/refresh-auth-token';\nimport { FirebaseInstallationsImpl } from '../interfaces/installation-impl';\nimport { Installations } from '../interfaces/public-types';\n\n/**\n * Returns a Firebase Installations auth token, identifying the current\n * Firebase Installation.\n * @param installations - The `Installations` instance.\n * @param forceRefresh - Force refresh regardless of token expiration.\n *\n * @public\n */\nexport async function getToken(\n installations: Installations,\n forceRefresh = false\n): Promise {\n const installationsImpl = installations as FirebaseInstallationsImpl;\n await completeInstallationRegistration(installationsImpl);\n\n // At this point we either have a Registered Installation in the DB, or we've\n // already thrown an error.\n const authToken = await refreshAuthToken(installationsImpl, forceRefresh);\n return authToken.token;\n}\n\nasync function completeInstallationRegistration(\n installations: FirebaseInstallationsImpl\n): Promise {\n const { registrationPromise } = await getInstallationEntry(installations);\n\n if (registrationPromise) {\n // A createInstallation request is in progress. Wait until it finishes.\n await registrationPromise;\n }\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { AppConfig } from '../interfaces/installation-impl';\nimport { RegisteredInstallationEntry } from '../interfaces/installation-entry';\nimport {\n getErrorFromResponse,\n getHeadersWithAuth,\n getInstallationsEndpoint,\n retryIfServerError\n} from './common';\n\nexport async function deleteInstallationRequest(\n appConfig: AppConfig,\n installationEntry: RegisteredInstallationEntry\n): Promise {\n const endpoint = getDeleteEndpoint(appConfig, installationEntry);\n\n const headers = getHeadersWithAuth(appConfig, installationEntry);\n const request: RequestInit = {\n method: 'DELETE',\n headers\n };\n\n const response = await retryIfServerError(() => fetch(endpoint, request));\n if (!response.ok) {\n throw await getErrorFromResponse('Delete Installation', response);\n }\n}\n\nfunction getDeleteEndpoint(\n appConfig: AppConfig,\n { fid }: RegisteredInstallationEntry\n): string {\n return `${getInstallationsEndpoint(appConfig)}/${fid}`;\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { deleteInstallationRequest } from '../functions/delete-installation-request';\nimport { remove, update } from '../helpers/idb-manager';\nimport { RequestStatus } from '../interfaces/installation-entry';\nimport { ERROR_FACTORY, ErrorCode } from '../util/errors';\nimport { FirebaseInstallationsImpl } from '../interfaces/installation-impl';\nimport { Installations } from '../interfaces/public-types';\n\n/**\n * Deletes the Firebase Installation and all associated data.\n * @param installations - The `Installations` instance.\n *\n * @public\n */\nexport async function deleteInstallations(\n installations: Installations\n): Promise {\n const { appConfig } = installations as FirebaseInstallationsImpl;\n\n const entry = await update(appConfig, oldEntry => {\n if (oldEntry && oldEntry.registrationStatus === RequestStatus.NOT_STARTED) {\n // Delete the unregistered entry without sending a deleteInstallation request.\n return undefined;\n }\n return oldEntry;\n });\n\n if (entry) {\n if (entry.registrationStatus === RequestStatus.IN_PROGRESS) {\n // Can't delete while trying to register.\n throw ERROR_FACTORY.create(ErrorCode.DELETE_PENDING_REGISTRATION);\n } else if (entry.registrationStatus === RequestStatus.COMPLETED) {\n if (!navigator.onLine) {\n throw ERROR_FACTORY.create(ErrorCode.APP_OFFLINE);\n } else {\n await deleteInstallationRequest(appConfig, entry);\n await remove(appConfig);\n }\n }\n }\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { addCallback, removeCallback } from '../helpers/fid-changed';\nimport { FirebaseInstallationsImpl } from '../interfaces/installation-impl';\nimport { Installations } from '../interfaces/public-types';\n\n/**\n * An user defined callback function that gets called when Installations ID changes.\n *\n * @public\n */\nexport type IdChangeCallbackFn = (installationId: string) => void;\n/**\n * Unsubscribe a callback function previously added via {@link IdChangeCallbackFn}.\n *\n * @public\n */\nexport type IdChangeUnsubscribeFn = () => void;\n\n/**\n * Sets a new callback that will get called when Installation ID changes.\n * Returns an unsubscribe function that will remove the callback when called.\n * @param installations - The `Installations` instance.\n * @param callback - The callback function that is invoked when FID changes.\n * @returns A function that can be called to unsubscribe.\n *\n * @public\n */\nexport function onIdChange(\n installations: Installations,\n callback: IdChangeCallbackFn\n): IdChangeUnsubscribeFn {\n const { appConfig } = installations as FirebaseInstallationsImpl;\n\n addCallback(appConfig, callback);\n return () => {\n removeCallback(appConfig, callback);\n };\n}\n", "/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { FirebaseApp, getApp, _getProvider } from '@firebase/app';\nimport { Installations } from '../interfaces/public-types';\n\n/**\n * Returns an instance of {@link Installations} associated with the given\n * {@link @firebase/app#FirebaseApp} instance.\n * @param app - The {@link @firebase/app#FirebaseApp} instance.\n *\n * @public\n */\nexport function getInstallations(app: FirebaseApp = getApp()): Installations {\n const installationsImpl = _getProvider(app, 'installations').getImmediate();\n return installationsImpl;\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { FirebaseApp, FirebaseOptions } from '@firebase/app';\nimport { FirebaseError } from '@firebase/util';\nimport { AppConfig } from '../interfaces/installation-impl';\nimport { ERROR_FACTORY, ErrorCode } from '../util/errors';\n\nexport function extractAppConfig(app: FirebaseApp): AppConfig {\n if (!app || !app.options) {\n throw getMissingValueError('App Configuration');\n }\n\n if (!app.name) {\n throw getMissingValueError('App Name');\n }\n\n // Required app config keys\n const configKeys: Array = [\n 'projectId',\n 'apiKey',\n 'appId'\n ];\n\n for (const keyName of configKeys) {\n if (!app.options[keyName]) {\n throw getMissingValueError(keyName);\n }\n }\n\n return {\n appName: app.name,\n projectId: app.options.projectId!,\n apiKey: app.options.apiKey!,\n appId: app.options.appId!\n };\n}\n\nfunction getMissingValueError(valueName: string): FirebaseError {\n return ERROR_FACTORY.create(ErrorCode.MISSING_APP_CONFIG_VALUES, {\n valueName\n });\n}\n", "/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { _registerComponent, _getProvider } from '@firebase/app';\nimport {\n Component,\n ComponentType,\n InstanceFactory,\n ComponentContainer\n} from '@firebase/component';\nimport { getId, getToken } from '../api/index';\nimport { _FirebaseInstallationsInternal } from '../interfaces/public-types';\nimport { FirebaseInstallationsImpl } from '../interfaces/installation-impl';\nimport { extractAppConfig } from '../helpers/extract-app-config';\n\nconst INSTALLATIONS_NAME = 'installations';\nconst INSTALLATIONS_NAME_INTERNAL = 'installations-internal';\n\nconst publicFactory: InstanceFactory<'installations'> = (\n container: ComponentContainer\n) => {\n const app = container.getProvider('app').getImmediate();\n // Throws if app isn't configured properly.\n const appConfig = extractAppConfig(app);\n const heartbeatServiceProvider = _getProvider(app, 'heartbeat');\n\n const installationsImpl: FirebaseInstallationsImpl = {\n app,\n appConfig,\n heartbeatServiceProvider,\n _delete: () => Promise.resolve()\n };\n return installationsImpl;\n};\n\nconst internalFactory: InstanceFactory<'installations-internal'> = (\n container: ComponentContainer\n) => {\n const app = container.getProvider('app').getImmediate();\n // Internal FIS instance relies on public FIS instance.\n const installations = _getProvider(app, INSTALLATIONS_NAME).getImmediate();\n\n const installationsInternal: _FirebaseInstallationsInternal = {\n getId: () => getId(installations),\n getToken: (forceRefresh?: boolean) => getToken(installations, forceRefresh)\n };\n return installationsInternal;\n};\n\nexport function registerInstallations(): void {\n _registerComponent(\n new Component(INSTALLATIONS_NAME, publicFactory, ComponentType.PUBLIC)\n );\n _registerComponent(\n new Component(\n INSTALLATIONS_NAME_INTERNAL,\n internalFactory,\n ComponentType.PRIVATE\n )\n );\n}\n", "/**\n * Firebase Installations\n *\n * @packageDocumentation\n */\n\n/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { registerInstallations } from './functions/config';\nimport { registerVersion } from '@firebase/app';\nimport { name, version } from '../package.json';\n\nexport * from './api';\nexport * from './interfaces/public-types';\n\nregisterInstallations();\nregisterVersion(name, version);\n// BUILD_TARGET will be replaced by values like esm5, esm2017, cjs5, etc during the compilation\nregisterVersion(name, version, '__BUILD_TARGET__');\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport const DEFAULT_SW_PATH = '/firebase-messaging-sw.js';\nexport const DEFAULT_SW_SCOPE = '/firebase-cloud-messaging-push-scope';\n\nexport const DEFAULT_VAPID_KEY =\n 'BDOU99-h67HcA6JeFXHbSNMu7e2yNNu3RzoMj8TM4W88jITfq7ZmPvIM1Iv-4_l2LxQcYwhqby2xGpWwzjfAnG4';\n\nexport const ENDPOINT = 'https://fcmregistrations.googleapis.com/v1';\n\n/** Key of FCM Payload in Notification's data field. */\nexport const FCM_MSG = 'FCM_MSG';\n\nexport const CONSOLE_CAMPAIGN_ID = 'google.c.a.c_id';\nexport const CONSOLE_CAMPAIGN_NAME = 'google.c.a.c_l';\nexport const CONSOLE_CAMPAIGN_TIME = 'google.c.a.ts';\n/** Set to '1' if Analytics is enabled for the campaign */\nexport const CONSOLE_CAMPAIGN_ANALYTICS_ENABLED = 'google.c.a.e';\nexport const TAG = 'FirebaseMessaging: ';\nexport const MAX_NUMBER_OF_EVENTS_PER_LOG_REQUEST = 1000;\nexport const MAX_RETRIES = 3;\nexport const LOG_INTERVAL_IN_MS = 86400000; //24 hour\nexport const DEFAULT_BACKOFF_TIME_MS = 5000;\n\n// FCM log source name registered at Firelog: 'FCM_CLIENT_EVENT_LOGGING'. It uniquely identifies\n// FCM's logging configuration.\nexport const FCM_LOG_SOURCE = 1249;\n\n// Defined as in proto/messaging_event.proto. Neglecting fields that are supported.\nexport const SDK_PLATFORM_WEB = 3;\nexport const EVENT_MESSAGE_DELIVERED = 1;\n\nexport enum MessageType {\n DATA_MESSAGE = 1,\n DISPLAY_NOTIFICATION = 3\n}\n", "/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License. You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under the License\n * is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n * or implied. See the License for the specific language governing permissions and limitations under\n * the License.\n */\n\nimport {\n CONSOLE_CAMPAIGN_ANALYTICS_ENABLED,\n CONSOLE_CAMPAIGN_ID,\n CONSOLE_CAMPAIGN_NAME,\n CONSOLE_CAMPAIGN_TIME\n} from '../util/constants';\n\nexport interface MessagePayloadInternal {\n notification?: NotificationPayloadInternal;\n data?: unknown;\n fcmOptions?: FcmOptionsInternal;\n messageType?: MessageType;\n isFirebaseMessaging?: boolean;\n from: string;\n fcmMessageId: string;\n // eslint-disable-next-line camelcase\n collapse_key: string;\n}\n\nexport interface NotificationPayloadInternal extends NotificationOptions {\n title: string;\n // Supported in the Legacy Send API.\n // See:https://firebase.google.com/docs/cloud-messaging/xmpp-server-ref.\n // eslint-disable-next-line camelcase\n click_action?: string;\n}\n\n// Defined in\n// https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages#webpushfcmoptions. Note\n// that the keys are sent to the clients in snake cases which we need to convert to camel so it can\n// be exposed as a type to match the Firebase API convention.\nexport interface FcmOptionsInternal {\n link?: string;\n\n // eslint-disable-next-line camelcase\n analytics_label?: string;\n}\n\nexport enum MessageType {\n PUSH_RECEIVED = 'push-received',\n NOTIFICATION_CLICKED = 'notification-clicked'\n}\n\n/** Additional data of a message sent from the FN Console. */\nexport interface ConsoleMessageData {\n [CONSOLE_CAMPAIGN_ID]: string;\n [CONSOLE_CAMPAIGN_TIME]: string;\n [CONSOLE_CAMPAIGN_NAME]?: string;\n [CONSOLE_CAMPAIGN_ANALYTICS_ENABLED]?: '1';\n}\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport function arrayToBase64(array: Uint8Array | ArrayBuffer): string {\n const uint8Array = new Uint8Array(array);\n const base64String = btoa(String.fromCharCode(...uint8Array));\n return base64String.replace(/=/g, '').replace(/\\+/g, '-').replace(/\\//g, '_');\n}\n\nexport function base64ToArray(base64String: string): Uint8Array {\n const padding = '='.repeat((4 - (base64String.length % 4)) % 4);\n const base64 = (base64String + padding)\n .replace(/\\-/g, '+')\n .replace(/_/g, '/');\n\n const rawData = atob(base64);\n const outputArray = new Uint8Array(rawData.length);\n\n for (let i = 0; i < rawData.length; ++i) {\n outputArray[i] = rawData.charCodeAt(i);\n }\n return outputArray;\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { deleteDB, openDB } from 'idb';\n\nimport { TokenDetails } from '../interfaces/token-details';\nimport { arrayToBase64 } from './array-base64-translator';\n\n// https://github.com/firebase/firebase-js-sdk/blob/7857c212f944a2a9eb421fd4cb7370181bc034b5/packages/messaging/src/interfaces/token-details.ts\nexport interface V2TokenDetails {\n fcmToken: string;\n swScope: string;\n vapidKey: string | Uint8Array;\n subscription: PushSubscription;\n fcmSenderId: string;\n fcmPushSet: string;\n createTime?: number;\n endpoint?: string;\n auth?: string;\n p256dh?: string;\n}\n\n// https://github.com/firebase/firebase-js-sdk/blob/6b5b15ce4ea3df5df5df8a8b33a4e41e249c7715/packages/messaging/src/interfaces/token-details.ts\nexport interface V3TokenDetails {\n fcmToken: string;\n swScope: string;\n vapidKey: Uint8Array;\n fcmSenderId: string;\n fcmPushSet: string;\n endpoint: string;\n auth: ArrayBuffer;\n p256dh: ArrayBuffer;\n createTime: number;\n}\n\n// https://github.com/firebase/firebase-js-sdk/blob/9567dba664732f681fa7fe60f5b7032bb1daf4c9/packages/messaging/src/interfaces/token-details.ts\nexport interface V4TokenDetails {\n fcmToken: string;\n swScope: string;\n vapidKey: Uint8Array;\n fcmSenderId: string;\n endpoint: string;\n auth: ArrayBufferLike;\n p256dh: ArrayBufferLike;\n createTime: number;\n}\n\nconst OLD_DB_NAME = 'fcm_token_details_db';\n/**\n * The last DB version of 'fcm_token_details_db' was 4. This is one higher, so that the upgrade\n * callback is called for all versions of the old DB.\n */\nconst OLD_DB_VERSION = 5;\nconst OLD_OBJECT_STORE_NAME = 'fcm_token_object_Store';\n\nexport async function migrateOldDatabase(\n senderId: string\n): Promise {\n if ('databases' in indexedDB) {\n // indexedDb.databases() is an IndexedDB v3 API and does not exist in all browsers. TODO: Remove\n // typecast when it lands in TS types.\n const databases = await (\n indexedDB as {\n databases(): Promise>;\n }\n ).databases();\n const dbNames = databases.map(db => db.name);\n\n if (!dbNames.includes(OLD_DB_NAME)) {\n // old DB didn't exist, no need to open.\n return null;\n }\n }\n\n let tokenDetails: TokenDetails | null = null;\n\n const db = await openDB(OLD_DB_NAME, OLD_DB_VERSION, {\n upgrade: async (db, oldVersion, newVersion, upgradeTransaction) => {\n if (oldVersion < 2) {\n // Database too old, skip migration.\n return;\n }\n\n if (!db.objectStoreNames.contains(OLD_OBJECT_STORE_NAME)) {\n // Database did not exist. Nothing to do.\n return;\n }\n\n const objectStore = upgradeTransaction.objectStore(OLD_OBJECT_STORE_NAME);\n const value = await objectStore.index('fcmSenderId').get(senderId);\n await objectStore.clear();\n\n if (!value) {\n // No entry in the database, nothing to migrate.\n return;\n }\n\n if (oldVersion === 2) {\n const oldDetails = value as V2TokenDetails;\n\n if (!oldDetails.auth || !oldDetails.p256dh || !oldDetails.endpoint) {\n return;\n }\n\n tokenDetails = {\n token: oldDetails.fcmToken,\n createTime: oldDetails.createTime ?? Date.now(),\n subscriptionOptions: {\n auth: oldDetails.auth,\n p256dh: oldDetails.p256dh,\n endpoint: oldDetails.endpoint,\n swScope: oldDetails.swScope,\n vapidKey:\n typeof oldDetails.vapidKey === 'string'\n ? oldDetails.vapidKey\n : arrayToBase64(oldDetails.vapidKey)\n }\n };\n } else if (oldVersion === 3) {\n const oldDetails = value as V3TokenDetails;\n\n tokenDetails = {\n token: oldDetails.fcmToken,\n createTime: oldDetails.createTime,\n subscriptionOptions: {\n auth: arrayToBase64(oldDetails.auth),\n p256dh: arrayToBase64(oldDetails.p256dh),\n endpoint: oldDetails.endpoint,\n swScope: oldDetails.swScope,\n vapidKey: arrayToBase64(oldDetails.vapidKey)\n }\n };\n } else if (oldVersion === 4) {\n const oldDetails = value as V4TokenDetails;\n\n tokenDetails = {\n token: oldDetails.fcmToken,\n createTime: oldDetails.createTime,\n subscriptionOptions: {\n auth: arrayToBase64(oldDetails.auth),\n p256dh: arrayToBase64(oldDetails.p256dh),\n endpoint: oldDetails.endpoint,\n swScope: oldDetails.swScope,\n vapidKey: arrayToBase64(oldDetails.vapidKey)\n }\n };\n }\n }\n });\n db.close();\n\n // Delete all old databases.\n await deleteDB(OLD_DB_NAME);\n await deleteDB('fcm_vapid_details_db');\n await deleteDB('undefined');\n\n return checkTokenDetails(tokenDetails) ? tokenDetails : null;\n}\n\nfunction checkTokenDetails(\n tokenDetails: TokenDetails | null\n): tokenDetails is TokenDetails {\n if (!tokenDetails || !tokenDetails.subscriptionOptions) {\n return false;\n }\n const { subscriptionOptions } = tokenDetails;\n return (\n typeof tokenDetails.createTime === 'number' &&\n tokenDetails.createTime > 0 &&\n typeof tokenDetails.token === 'string' &&\n tokenDetails.token.length > 0 &&\n typeof subscriptionOptions.auth === 'string' &&\n subscriptionOptions.auth.length > 0 &&\n typeof subscriptionOptions.p256dh === 'string' &&\n subscriptionOptions.p256dh.length > 0 &&\n typeof subscriptionOptions.endpoint === 'string' &&\n subscriptionOptions.endpoint.length > 0 &&\n typeof subscriptionOptions.swScope === 'string' &&\n subscriptionOptions.swScope.length > 0 &&\n typeof subscriptionOptions.vapidKey === 'string' &&\n subscriptionOptions.vapidKey.length > 0\n );\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { DBSchema, IDBPDatabase, deleteDB, openDB } from 'idb';\n\nimport { FirebaseInternalDependencies } from '../interfaces/internal-dependencies';\nimport { TokenDetails } from '../interfaces/token-details';\nimport { migrateOldDatabase } from '../helpers/migrate-old-database';\n\n// Exported for tests.\nexport const DATABASE_NAME = 'firebase-messaging-database';\nconst DATABASE_VERSION = 1;\nconst OBJECT_STORE_NAME = 'firebase-messaging-store';\n\ninterface MessagingDB extends DBSchema {\n 'firebase-messaging-store': {\n key: string;\n value: TokenDetails;\n };\n}\n\nlet dbPromise: Promise> | null = null;\nfunction getDbPromise(): Promise> {\n if (!dbPromise) {\n dbPromise = openDB(DATABASE_NAME, DATABASE_VERSION, {\n upgrade: (upgradeDb, oldVersion) => {\n // We don't use 'break' in this switch statement, the fall-through behavior is what we want,\n // because if there are multiple versions between the old version and the current version, we\n // want ALL the migrations that correspond to those versions to run, not only the last one.\n // eslint-disable-next-line default-case\n switch (oldVersion) {\n case 0:\n upgradeDb.createObjectStore(OBJECT_STORE_NAME);\n }\n }\n });\n }\n return dbPromise;\n}\n\n/** Gets record(s) from the objectStore that match the given key. */\nexport async function dbGet(\n firebaseDependencies: FirebaseInternalDependencies\n): Promise {\n const key = getKey(firebaseDependencies);\n const db = await getDbPromise();\n const tokenDetails = (await db\n .transaction(OBJECT_STORE_NAME)\n .objectStore(OBJECT_STORE_NAME)\n .get(key)) as TokenDetails;\n\n if (tokenDetails) {\n return tokenDetails;\n } else {\n // Check if there is a tokenDetails object in the old DB.\n const oldTokenDetails = await migrateOldDatabase(\n firebaseDependencies.appConfig.senderId\n );\n if (oldTokenDetails) {\n await dbSet(firebaseDependencies, oldTokenDetails);\n return oldTokenDetails;\n }\n }\n}\n\n/** Assigns or overwrites the record for the given key with the given value. */\nexport async function dbSet(\n firebaseDependencies: FirebaseInternalDependencies,\n tokenDetails: TokenDetails\n): Promise {\n const key = getKey(firebaseDependencies);\n const db = await getDbPromise();\n const tx = db.transaction(OBJECT_STORE_NAME, 'readwrite');\n await tx.objectStore(OBJECT_STORE_NAME).put(tokenDetails, key);\n await tx.done;\n return tokenDetails;\n}\n\n/** Removes record(s) from the objectStore that match the given key. */\nexport async function dbRemove(\n firebaseDependencies: FirebaseInternalDependencies\n): Promise {\n const key = getKey(firebaseDependencies);\n const db = await getDbPromise();\n const tx = db.transaction(OBJECT_STORE_NAME, 'readwrite');\n await tx.objectStore(OBJECT_STORE_NAME).delete(key);\n await tx.done;\n}\n\n/** Deletes the DB. Useful for tests. */\nexport async function dbDelete(): Promise {\n if (dbPromise) {\n (await dbPromise).close();\n await deleteDB(DATABASE_NAME);\n dbPromise = null;\n }\n}\n\nfunction getKey({ appConfig }: FirebaseInternalDependencies): string {\n return appConfig.appId;\n}\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ErrorFactory, ErrorMap } from '@firebase/util';\n\nexport const enum ErrorCode {\n MISSING_APP_CONFIG_VALUES = 'missing-app-config-values',\n AVAILABLE_IN_WINDOW = 'only-available-in-window',\n AVAILABLE_IN_SW = 'only-available-in-sw',\n PERMISSION_DEFAULT = 'permission-default',\n PERMISSION_BLOCKED = 'permission-blocked',\n UNSUPPORTED_BROWSER = 'unsupported-browser',\n INDEXED_DB_UNSUPPORTED = 'indexed-db-unsupported',\n FAILED_DEFAULT_REGISTRATION = 'failed-service-worker-registration',\n TOKEN_SUBSCRIBE_FAILED = 'token-subscribe-failed',\n TOKEN_SUBSCRIBE_NO_TOKEN = 'token-subscribe-no-token',\n TOKEN_UNSUBSCRIBE_FAILED = 'token-unsubscribe-failed',\n TOKEN_UPDATE_FAILED = 'token-update-failed',\n TOKEN_UPDATE_NO_TOKEN = 'token-update-no-token',\n INVALID_BG_HANDLER = 'invalid-bg-handler',\n USE_SW_AFTER_GET_TOKEN = 'use-sw-after-get-token',\n INVALID_SW_REGISTRATION = 'invalid-sw-registration',\n USE_VAPID_KEY_AFTER_GET_TOKEN = 'use-vapid-key-after-get-token',\n INVALID_VAPID_KEY = 'invalid-vapid-key'\n}\n\nexport const ERROR_MAP: ErrorMap = {\n [ErrorCode.MISSING_APP_CONFIG_VALUES]:\n 'Missing App configuration value: \"{$valueName}\"',\n [ErrorCode.AVAILABLE_IN_WINDOW]:\n 'This method is available in a Window context.',\n [ErrorCode.AVAILABLE_IN_SW]:\n 'This method is available in a service worker context.',\n [ErrorCode.PERMISSION_DEFAULT]:\n 'The notification permission was not granted and dismissed instead.',\n [ErrorCode.PERMISSION_BLOCKED]:\n 'The notification permission was not granted and blocked instead.',\n [ErrorCode.UNSUPPORTED_BROWSER]:\n \"This browser doesn't support the API's required to use the Firebase SDK.\",\n [ErrorCode.INDEXED_DB_UNSUPPORTED]:\n \"This browser doesn't support indexedDb.open() (ex. Safari iFrame, Firefox Private Browsing, etc)\",\n [ErrorCode.FAILED_DEFAULT_REGISTRATION]:\n 'We are unable to register the default service worker. {$browserErrorMessage}',\n [ErrorCode.TOKEN_SUBSCRIBE_FAILED]:\n 'A problem occurred while subscribing the user to FCM: {$errorInfo}',\n [ErrorCode.TOKEN_SUBSCRIBE_NO_TOKEN]:\n 'FCM returned no token when subscribing the user to push.',\n [ErrorCode.TOKEN_UNSUBSCRIBE_FAILED]:\n 'A problem occurred while unsubscribing the ' +\n 'user from FCM: {$errorInfo}',\n [ErrorCode.TOKEN_UPDATE_FAILED]:\n 'A problem occurred while updating the user from FCM: {$errorInfo}',\n [ErrorCode.TOKEN_UPDATE_NO_TOKEN]:\n 'FCM returned no token when updating the user to push.',\n [ErrorCode.USE_SW_AFTER_GET_TOKEN]:\n 'The useServiceWorker() method may only be called once and must be ' +\n 'called before calling getToken() to ensure your service worker is used.',\n [ErrorCode.INVALID_SW_REGISTRATION]:\n 'The input to useServiceWorker() must be a ServiceWorkerRegistration.',\n [ErrorCode.INVALID_BG_HANDLER]:\n 'The input to setBackgroundMessageHandler() must be a function.',\n [ErrorCode.INVALID_VAPID_KEY]: 'The public VAPID key must be a string.',\n [ErrorCode.USE_VAPID_KEY_AFTER_GET_TOKEN]:\n 'The usePublicVapidKey() method may only be called once and must be ' +\n 'called before calling getToken() to ensure your VAPID key is used.'\n};\n\ninterface ErrorParams {\n [ErrorCode.MISSING_APP_CONFIG_VALUES]: {\n valueName: string;\n };\n [ErrorCode.FAILED_DEFAULT_REGISTRATION]: { browserErrorMessage: string };\n [ErrorCode.TOKEN_SUBSCRIBE_FAILED]: { errorInfo: string };\n [ErrorCode.TOKEN_UNSUBSCRIBE_FAILED]: { errorInfo: string };\n [ErrorCode.TOKEN_UPDATE_FAILED]: { errorInfo: string };\n}\n\nexport const ERROR_FACTORY = new ErrorFactory(\n 'messaging',\n 'Messaging',\n ERROR_MAP\n);\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { DEFAULT_VAPID_KEY, ENDPOINT } from '../util/constants';\nimport { ERROR_FACTORY, ErrorCode } from '../util/errors';\nimport { SubscriptionOptions, TokenDetails } from '../interfaces/token-details';\n\nimport { AppConfig } from '../interfaces/app-config';\nimport { FirebaseInternalDependencies } from '../interfaces/internal-dependencies';\n\nexport interface ApiResponse {\n token?: string;\n error?: { message: string };\n}\n\nexport interface ApiRequestBody {\n web: {\n endpoint: string;\n p256dh: string;\n auth: string;\n applicationPubKey?: string;\n };\n}\n\nexport async function requestGetToken(\n firebaseDependencies: FirebaseInternalDependencies,\n subscriptionOptions: SubscriptionOptions\n): Promise {\n const headers = await getHeaders(firebaseDependencies);\n const body = getBody(subscriptionOptions);\n\n const subscribeOptions = {\n method: 'POST',\n headers,\n body: JSON.stringify(body)\n };\n\n let responseData: ApiResponse;\n try {\n const response = await fetch(\n getEndpoint(firebaseDependencies.appConfig),\n subscribeOptions\n );\n responseData = await response.json();\n } catch (err) {\n throw ERROR_FACTORY.create(ErrorCode.TOKEN_SUBSCRIBE_FAILED, {\n errorInfo: (err as Error)?.toString()\n });\n }\n\n if (responseData.error) {\n const message = responseData.error.message;\n throw ERROR_FACTORY.create(ErrorCode.TOKEN_SUBSCRIBE_FAILED, {\n errorInfo: message\n });\n }\n\n if (!responseData.token) {\n throw ERROR_FACTORY.create(ErrorCode.TOKEN_SUBSCRIBE_NO_TOKEN);\n }\n\n return responseData.token;\n}\n\nexport async function requestUpdateToken(\n firebaseDependencies: FirebaseInternalDependencies,\n tokenDetails: TokenDetails\n): Promise {\n const headers = await getHeaders(firebaseDependencies);\n const body = getBody(tokenDetails.subscriptionOptions!);\n\n const updateOptions = {\n method: 'PATCH',\n headers,\n body: JSON.stringify(body)\n };\n\n let responseData: ApiResponse;\n try {\n const response = await fetch(\n `${getEndpoint(firebaseDependencies.appConfig)}/${tokenDetails.token}`,\n updateOptions\n );\n responseData = await response.json();\n } catch (err) {\n throw ERROR_FACTORY.create(ErrorCode.TOKEN_UPDATE_FAILED, {\n errorInfo: (err as Error)?.toString()\n });\n }\n\n if (responseData.error) {\n const message = responseData.error.message;\n throw ERROR_FACTORY.create(ErrorCode.TOKEN_UPDATE_FAILED, {\n errorInfo: message\n });\n }\n\n if (!responseData.token) {\n throw ERROR_FACTORY.create(ErrorCode.TOKEN_UPDATE_NO_TOKEN);\n }\n\n return responseData.token;\n}\n\nexport async function requestDeleteToken(\n firebaseDependencies: FirebaseInternalDependencies,\n token: string\n): Promise {\n const headers = await getHeaders(firebaseDependencies);\n\n const unsubscribeOptions = {\n method: 'DELETE',\n headers\n };\n\n try {\n const response = await fetch(\n `${getEndpoint(firebaseDependencies.appConfig)}/${token}`,\n unsubscribeOptions\n );\n const responseData: ApiResponse = await response.json();\n if (responseData.error) {\n const message = responseData.error.message;\n throw ERROR_FACTORY.create(ErrorCode.TOKEN_UNSUBSCRIBE_FAILED, {\n errorInfo: message\n });\n }\n } catch (err) {\n throw ERROR_FACTORY.create(ErrorCode.TOKEN_UNSUBSCRIBE_FAILED, {\n errorInfo: (err as Error)?.toString()\n });\n }\n}\n\nfunction getEndpoint({ projectId }: AppConfig): string {\n return `${ENDPOINT}/projects/${projectId!}/registrations`;\n}\n\nasync function getHeaders({\n appConfig,\n installations\n}: FirebaseInternalDependencies): Promise {\n const authToken = await installations.getToken();\n\n return new Headers({\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n 'x-goog-api-key': appConfig.apiKey!,\n 'x-goog-firebase-installations-auth': `FIS ${authToken}`\n });\n}\n\nfunction getBody({\n p256dh,\n auth,\n endpoint,\n vapidKey\n}: SubscriptionOptions): ApiRequestBody {\n const body: ApiRequestBody = {\n web: {\n endpoint,\n auth,\n p256dh\n }\n };\n\n if (vapidKey !== DEFAULT_VAPID_KEY) {\n body.web.applicationPubKey = vapidKey;\n }\n\n return body;\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { SubscriptionOptions, TokenDetails } from '../interfaces/token-details';\nimport {\n arrayToBase64,\n base64ToArray\n} from '../helpers/array-base64-translator';\nimport { dbGet, dbRemove, dbSet } from './idb-manager';\nimport {\n requestDeleteToken,\n requestGetToken,\n requestUpdateToken\n} from './requests';\n\nimport { FirebaseInternalDependencies } from '../interfaces/internal-dependencies';\nimport { MessagingService } from '../messaging-service';\n\n// UpdateRegistration will be called once every week.\nconst TOKEN_EXPIRATION_MS = 7 * 24 * 60 * 60 * 1000; // 7 days\n\nexport async function getTokenInternal(\n messaging: MessagingService\n): Promise {\n const pushSubscription = await getPushSubscription(\n messaging.swRegistration!,\n messaging.vapidKey!\n );\n\n const subscriptionOptions: SubscriptionOptions = {\n vapidKey: messaging.vapidKey!,\n swScope: messaging.swRegistration!.scope,\n endpoint: pushSubscription.endpoint,\n auth: arrayToBase64(pushSubscription.getKey('auth')!),\n p256dh: arrayToBase64(pushSubscription.getKey('p256dh')!)\n };\n\n const tokenDetails = await dbGet(messaging.firebaseDependencies);\n if (!tokenDetails) {\n // No token, get a new one.\n return getNewToken(messaging.firebaseDependencies, subscriptionOptions);\n } else if (\n !isTokenValid(tokenDetails.subscriptionOptions!, subscriptionOptions)\n ) {\n // Invalid token, get a new one.\n try {\n await requestDeleteToken(\n messaging.firebaseDependencies!,\n tokenDetails.token\n );\n } catch (e) {\n // Suppress errors because of #2364\n console.warn(e);\n }\n\n return getNewToken(messaging.firebaseDependencies!, subscriptionOptions);\n } else if (Date.now() >= tokenDetails.createTime + TOKEN_EXPIRATION_MS) {\n // Weekly token refresh\n return updateToken(messaging, {\n token: tokenDetails.token,\n createTime: Date.now(),\n subscriptionOptions\n });\n } else {\n // Valid token, nothing to do.\n return tokenDetails.token;\n }\n}\n\n/**\n * This method deletes the token from the database, unsubscribes the token from FCM, and unregisters\n * the push subscription if it exists.\n */\nexport async function deleteTokenInternal(\n messaging: MessagingService\n): Promise {\n const tokenDetails = await dbGet(messaging.firebaseDependencies);\n if (tokenDetails) {\n await requestDeleteToken(\n messaging.firebaseDependencies,\n tokenDetails.token\n );\n await dbRemove(messaging.firebaseDependencies);\n }\n\n // Unsubscribe from the push subscription.\n const pushSubscription =\n await messaging.swRegistration!.pushManager.getSubscription();\n if (pushSubscription) {\n return pushSubscription.unsubscribe();\n }\n\n // If there's no SW, consider it a success.\n return true;\n}\n\nasync function updateToken(\n messaging: MessagingService,\n tokenDetails: TokenDetails\n): Promise {\n try {\n const updatedToken = await requestUpdateToken(\n messaging.firebaseDependencies,\n tokenDetails\n );\n\n const updatedTokenDetails: TokenDetails = {\n ...tokenDetails,\n token: updatedToken,\n createTime: Date.now()\n };\n\n await dbSet(messaging.firebaseDependencies, updatedTokenDetails);\n return updatedToken;\n } catch (e) {\n await deleteTokenInternal(messaging);\n throw e;\n }\n}\n\nasync function getNewToken(\n firebaseDependencies: FirebaseInternalDependencies,\n subscriptionOptions: SubscriptionOptions\n): Promise {\n const token = await requestGetToken(\n firebaseDependencies,\n subscriptionOptions\n );\n const tokenDetails: TokenDetails = {\n token,\n createTime: Date.now(),\n subscriptionOptions\n };\n await dbSet(firebaseDependencies, tokenDetails);\n return tokenDetails.token;\n}\n\n/**\n * Gets a PushSubscription for the current user.\n */\nasync function getPushSubscription(\n swRegistration: ServiceWorkerRegistration,\n vapidKey: string\n): Promise {\n const subscription = await swRegistration.pushManager.getSubscription();\n if (subscription) {\n return subscription;\n }\n\n return swRegistration.pushManager.subscribe({\n userVisibleOnly: true,\n // Chrome <= 75 doesn't support base64-encoded VAPID key. For backward compatibility, VAPID key\n // submitted to pushManager#subscribe must be of type Uint8Array.\n applicationServerKey: base64ToArray(vapidKey)\n });\n}\n\n/**\n * Checks if the saved tokenDetails object matches the configuration provided.\n */\nfunction isTokenValid(\n dbOptions: SubscriptionOptions,\n currentOptions: SubscriptionOptions\n): boolean {\n const isVapidKeyEqual = currentOptions.vapidKey === dbOptions.vapidKey;\n const isEndpointEqual = currentOptions.endpoint === dbOptions.endpoint;\n const isAuthEqual = currentOptions.auth === dbOptions.auth;\n const isP256dhEqual = currentOptions.p256dh === dbOptions.p256dh;\n\n return isVapidKeyEqual && isEndpointEqual && isAuthEqual && isP256dhEqual;\n}\n", "/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { MessagePayload } from '../interfaces/public-types';\nimport { MessagePayloadInternal } from '../interfaces/internal-message-payload';\n\nexport function externalizePayload(\n internalPayload: MessagePayloadInternal\n): MessagePayload {\n const payload: MessagePayload = {\n from: internalPayload.from,\n // eslint-disable-next-line camelcase\n collapseKey: internalPayload.collapse_key,\n // eslint-disable-next-line camelcase\n messageId: internalPayload.fcmMessageId\n } as MessagePayload;\n\n propagateNotificationPayload(payload, internalPayload);\n propagateDataPayload(payload, internalPayload);\n propagateFcmOptions(payload, internalPayload);\n\n return payload;\n}\n\nfunction propagateNotificationPayload(\n payload: MessagePayload,\n messagePayloadInternal: MessagePayloadInternal\n): void {\n if (!messagePayloadInternal.notification) {\n return;\n }\n\n payload.notification = {};\n\n const title = messagePayloadInternal.notification!.title;\n if (!!title) {\n payload.notification!.title = title;\n }\n\n const body = messagePayloadInternal.notification!.body;\n if (!!body) {\n payload.notification!.body = body;\n }\n\n const image = messagePayloadInternal.notification!.image;\n if (!!image) {\n payload.notification!.image = image;\n }\n}\n\nfunction propagateDataPayload(\n payload: MessagePayload,\n messagePayloadInternal: MessagePayloadInternal\n): void {\n if (!messagePayloadInternal.data) {\n return;\n }\n\n payload.data = messagePayloadInternal.data as { [key: string]: string };\n}\n\nfunction propagateFcmOptions(\n payload: MessagePayload,\n messagePayloadInternal: MessagePayloadInternal\n): void {\n // fcmOptions.link value is written into notification.click_action. see more in b/232072111\n if (\n !messagePayloadInternal.fcmOptions &&\n !messagePayloadInternal.notification?.click_action\n ) {\n return;\n }\n\n payload.fcmOptions = {};\n\n const link =\n messagePayloadInternal.fcmOptions?.link ??\n messagePayloadInternal.notification?.click_action;\n\n if (!!link) {\n payload.fcmOptions!.link = link;\n }\n\n // eslint-disable-next-line camelcase\n const analyticsLabel = messagePayloadInternal.fcmOptions?.analytics_label;\n if (!!analyticsLabel) {\n payload.fcmOptions!.analyticsLabel = analyticsLabel;\n }\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { CONSOLE_CAMPAIGN_ID } from '../util/constants';\nimport { ConsoleMessageData } from '../interfaces/internal-message-payload';\n\nexport function isConsoleMessage(data: unknown): data is ConsoleMessageData {\n // This message has a campaign ID, meaning it was sent using the Firebase Console.\n return typeof data === 'object' && !!data && CONSOLE_CAMPAIGN_ID in data;\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/** Returns a promise that resolves after given time passes. */\nexport function sleep(ms: number): Promise {\n return new Promise(resolve => {\n setTimeout(resolve, ms);\n });\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n DEFAULT_BACKOFF_TIME_MS,\n EVENT_MESSAGE_DELIVERED,\n FCM_LOG_SOURCE,\n LOG_INTERVAL_IN_MS,\n MAX_NUMBER_OF_EVENTS_PER_LOG_REQUEST,\n MAX_RETRIES,\n MessageType,\n SDK_PLATFORM_WEB\n} from '../util/constants';\nimport {\n FcmEvent,\n LogEvent,\n LogRequest,\n LogResponse\n} from '../interfaces/logging-types';\n\nimport { MessagePayloadInternal } from '../interfaces/internal-message-payload';\nimport { MessagingService } from '../messaging-service';\n\nconst FIRELOG_ENDPOINT = _mergeStrings(\n 'hts/frbslgigp.ogepscmv/ieo/eaylg',\n 'tp:/ieaeogn-agolai.o/1frlglgc/o'\n);\n\nconst FCM_TRANSPORT_KEY = _mergeStrings(\n 'AzSCbw63g1R0nCw85jG8',\n 'Iaya3yLKwmgvh7cF0q4'\n);\n\nexport function startLoggingService(messaging: MessagingService): void {\n if (!messaging.isLogServiceStarted) {\n _processQueue(messaging, LOG_INTERVAL_IN_MS);\n messaging.isLogServiceStarted = true;\n }\n}\n\n/**\n *\n * @param messaging the messaging instance.\n * @param offsetInMs this method execute after `offsetInMs` elapsed .\n */\nexport function _processQueue(\n messaging: MessagingService,\n offsetInMs: number\n): void {\n setTimeout(async () => {\n if (!messaging.deliveryMetricsExportedToBigQueryEnabled) {\n // flush events and terminate logging service\n messaging.logEvents = [];\n messaging.isLogServiceStarted = false;\n\n return;\n }\n\n if (!messaging.logEvents.length) {\n return _processQueue(messaging, LOG_INTERVAL_IN_MS);\n }\n\n await _dispatchLogEvents(messaging);\n }, offsetInMs);\n}\n\nexport async function _dispatchLogEvents(\n messaging: MessagingService\n): Promise {\n for (\n let i = 0, n = messaging.logEvents.length;\n i < n;\n i += MAX_NUMBER_OF_EVENTS_PER_LOG_REQUEST\n ) {\n const logRequest = _createLogRequest(\n messaging.logEvents.slice(i, i + MAX_NUMBER_OF_EVENTS_PER_LOG_REQUEST)\n );\n\n let retryCount = 0,\n response = {} as Response;\n\n do {\n try {\n response = await fetch(\n FIRELOG_ENDPOINT.concat('?key=', FCM_TRANSPORT_KEY),\n {\n method: 'POST',\n body: JSON.stringify(logRequest)\n }\n );\n\n // don't retry on 200s or non retriable errors\n if (response.ok || (!response.ok && !isRetriableError(response))) {\n break;\n }\n\n if (!response.ok && isRetriableError(response)) {\n // rethrow to retry with quota\n throw new Error(\n 'a retriable Non-200 code is returned in fetch to Firelog endpoint. Retry'\n );\n }\n } catch (error) {\n const isLastAttempt = retryCount === MAX_RETRIES;\n if (isLastAttempt) {\n // existing the do-while interactive retry logic because retry quota has reached.\n break;\n }\n }\n\n let delayInMs: number;\n try {\n delayInMs = Number(\n ((await response.json()) as LogResponse).nextRequestWaitMillis\n );\n } catch (e) {\n delayInMs = DEFAULT_BACKOFF_TIME_MS;\n }\n\n await new Promise(resolve => setTimeout(resolve, delayInMs));\n\n retryCount++;\n } while (retryCount < MAX_RETRIES);\n }\n\n messaging.logEvents = [];\n // schedule for next logging\n _processQueue(messaging, LOG_INTERVAL_IN_MS);\n}\n\nfunction isRetriableError(response: Response): boolean {\n const httpStatus = response.status;\n\n return (\n httpStatus === 429 ||\n httpStatus === 500 ||\n httpStatus === 503 ||\n httpStatus === 504\n );\n}\n\nexport async function stageLog(\n messaging: MessagingService,\n internalPayload: MessagePayloadInternal\n): Promise {\n const fcmEvent = createFcmEvent(\n internalPayload,\n await messaging.firebaseDependencies.installations.getId()\n );\n\n createAndEnqueueLogEvent(messaging, fcmEvent);\n}\n\nfunction createFcmEvent(\n internalPayload: MessagePayloadInternal,\n fid: string\n): FcmEvent {\n const fcmEvent = {} as FcmEvent;\n\n /* eslint-disable camelcase */\n // some fields should always be non-null. Still check to ensure.\n if (!!internalPayload.from) {\n fcmEvent.project_number = internalPayload.from;\n }\n\n if (!!internalPayload.fcmMessageId) {\n fcmEvent.message_id = internalPayload.fcmMessageId;\n }\n\n fcmEvent.instance_id = fid;\n\n if (!!internalPayload.notification) {\n fcmEvent.message_type = MessageType.DISPLAY_NOTIFICATION.toString();\n } else {\n fcmEvent.message_type = MessageType.DATA_MESSAGE.toString();\n }\n\n fcmEvent.sdk_platform = SDK_PLATFORM_WEB.toString();\n fcmEvent.package_name = self.origin.replace(/(^\\w+:|^)\\/\\//, '');\n\n if (!!internalPayload.collapse_key) {\n fcmEvent.collapse_key = internalPayload.collapse_key;\n }\n\n fcmEvent.event = EVENT_MESSAGE_DELIVERED.toString();\n\n if (!!internalPayload.fcmOptions?.analytics_label) {\n fcmEvent.analytics_label = internalPayload.fcmOptions?.analytics_label;\n }\n\n /* eslint-enable camelcase */\n return fcmEvent;\n}\n\nfunction createAndEnqueueLogEvent(\n messaging: MessagingService,\n fcmEvent: FcmEvent\n): void {\n const logEvent = {} as LogEvent;\n\n /* eslint-disable camelcase */\n logEvent.event_time_ms = Math.floor(Date.now()).toString();\n logEvent.source_extension_json_proto3 = JSON.stringify(fcmEvent);\n // eslint-disable-next-line camelcase\n\n messaging.logEvents.push(logEvent);\n}\n\nexport function _createLogRequest(logEventQueue: LogEvent[]): LogRequest {\n const logRequest = {} as LogRequest;\n\n /* eslint-disable camelcase */\n logRequest.log_source = FCM_LOG_SOURCE.toString();\n logRequest.log_event = logEventQueue;\n /* eslint-enable camelcase */\n\n return logRequest;\n}\n\nexport function _mergeStrings(s1: string, s2: string): string {\n const resultArray = [];\n for (let i = 0; i < s1.length; i++) {\n resultArray.push(s1.charAt(i));\n if (i < s2.length) {\n resultArray.push(s2.charAt(i));\n }\n }\n\n return resultArray.join('');\n}\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { DEFAULT_VAPID_KEY, FCM_MSG } from '../util/constants';\nimport {\n MessagePayloadInternal,\n MessageType,\n NotificationPayloadInternal\n} from '../interfaces/internal-message-payload';\nimport {\n NotificationEvent,\n PushEvent,\n PushSubscriptionChangeEvent,\n ServiceWorkerGlobalScope,\n WindowClient\n} from '../util/sw-types';\nimport {\n deleteTokenInternal,\n getTokenInternal\n} from '../internals/token-manager';\n\nimport { MessagingService } from '../messaging-service';\nimport { dbGet } from '../internals/idb-manager';\nimport { externalizePayload } from '../helpers/externalizePayload';\nimport { isConsoleMessage } from '../helpers/is-console-message';\nimport { sleep } from '../helpers/sleep';\nimport { stageLog } from '../helpers/logToFirelog';\n\n// Let TS know that this is a service worker\ndeclare const self: ServiceWorkerGlobalScope;\n\nexport async function onSubChange(\n event: PushSubscriptionChangeEvent,\n messaging: MessagingService\n): Promise {\n const { newSubscription } = event;\n if (!newSubscription) {\n // Subscription revoked, delete token\n await deleteTokenInternal(messaging);\n return;\n }\n\n const tokenDetails = await dbGet(messaging.firebaseDependencies);\n await deleteTokenInternal(messaging);\n\n messaging.vapidKey =\n tokenDetails?.subscriptionOptions?.vapidKey ?? DEFAULT_VAPID_KEY;\n await getTokenInternal(messaging);\n}\n\nexport async function onPush(\n event: PushEvent,\n messaging: MessagingService\n): Promise {\n const internalPayload = getMessagePayloadInternal(event);\n if (!internalPayload) {\n // Failed to get parsed MessagePayload from the PushEvent. Skip handling the push.\n return;\n }\n\n // log to Firelog with user consent\n if (messaging.deliveryMetricsExportedToBigQueryEnabled) {\n await stageLog(messaging, internalPayload);\n }\n\n // foreground handling: eventually passed to onMessage hook\n const clientList = await getClientList();\n if (hasVisibleClients(clientList)) {\n return sendMessagePayloadInternalToWindows(clientList, internalPayload);\n }\n\n // background handling: display if possible and pass to onBackgroundMessage hook\n if (!!internalPayload.notification) {\n await showNotification(wrapInternalPayload(internalPayload));\n }\n\n if (!messaging) {\n return;\n }\n\n if (!!messaging.onBackgroundMessageHandler) {\n const payload = externalizePayload(internalPayload);\n\n if (typeof messaging.onBackgroundMessageHandler === 'function') {\n await messaging.onBackgroundMessageHandler(payload);\n } else {\n messaging.onBackgroundMessageHandler.next(payload);\n }\n }\n}\n\nexport async function onNotificationClick(\n event: NotificationEvent\n): Promise {\n const internalPayload: MessagePayloadInternal =\n event.notification?.data?.[FCM_MSG];\n\n if (!internalPayload) {\n return;\n } else if (event.action) {\n // User clicked on an action button. This will allow developers to act on action button clicks\n // by using a custom onNotificationClick listener that they define.\n return;\n }\n\n // Prevent other listeners from receiving the event\n event.stopImmediatePropagation();\n event.notification.close();\n\n // Note clicking on a notification with no link set will focus the Chrome's current tab.\n const link = getLink(internalPayload);\n if (!link) {\n return;\n }\n\n // FM should only open/focus links from app's origin.\n const url = new URL(link, self.location.href);\n const originUrl = new URL(self.location.origin);\n\n if (url.host !== originUrl.host) {\n return;\n }\n\n let client = await getWindowClient(url);\n\n if (!client) {\n client = await self.clients.openWindow(link);\n\n // Wait three seconds for the client to initialize and set up the message handler so that it\n // can receive the message.\n await sleep(3000);\n } else {\n client = await client.focus();\n }\n\n if (!client) {\n // Window Client will not be returned if it's for a third party origin.\n return;\n }\n\n internalPayload.messageType = MessageType.NOTIFICATION_CLICKED;\n internalPayload.isFirebaseMessaging = true;\n return client.postMessage(internalPayload);\n}\n\nfunction wrapInternalPayload(\n internalPayload: MessagePayloadInternal\n): NotificationPayloadInternal {\n const wrappedInternalPayload: NotificationPayloadInternal = {\n ...(internalPayload.notification as unknown as NotificationPayloadInternal)\n };\n\n // Put the message payload under FCM_MSG name so we can identify the notification as being an FCM\n // notification vs a notification from somewhere else (i.e. normal web push or developer generated\n // notification).\n wrappedInternalPayload.data = {\n [FCM_MSG]: internalPayload\n };\n\n return wrappedInternalPayload;\n}\n\nfunction getMessagePayloadInternal({\n data\n}: PushEvent): MessagePayloadInternal | null {\n if (!data) {\n return null;\n }\n\n try {\n return data.json();\n } catch (err) {\n // Not JSON so not an FCM message.\n return null;\n }\n}\n\n/**\n * @param url The URL to look for when focusing a client.\n * @return Returns an existing window client or a newly opened WindowClient.\n */\nasync function getWindowClient(url: URL): Promise {\n const clientList = await getClientList();\n\n for (const client of clientList) {\n const clientUrl = new URL(client.url, self.location.href);\n\n if (url.host === clientUrl.host) {\n return client;\n }\n }\n\n return null;\n}\n\n/**\n * @returns If there is currently a visible WindowClient, this method will resolve to true,\n * otherwise false.\n */\nfunction hasVisibleClients(clientList: WindowClient[]): boolean {\n return clientList.some(\n client =>\n client.visibilityState === 'visible' &&\n // Ignore chrome-extension clients as that matches the background pages of extensions, which\n // are always considered visible for some reason.\n !client.url.startsWith('chrome-extension://')\n );\n}\n\nfunction sendMessagePayloadInternalToWindows(\n clientList: WindowClient[],\n internalPayload: MessagePayloadInternal\n): void {\n internalPayload.isFirebaseMessaging = true;\n internalPayload.messageType = MessageType.PUSH_RECEIVED;\n\n for (const client of clientList) {\n client.postMessage(internalPayload);\n }\n}\n\nfunction getClientList(): Promise {\n return self.clients.matchAll({\n type: 'window',\n includeUncontrolled: true\n // TS doesn't know that \"type: 'window'\" means it'll return WindowClient[]\n }) as Promise;\n}\n\nfunction showNotification(\n notificationPayloadInternal: NotificationPayloadInternal\n): Promise {\n // Note: Firefox does not support the maxActions property.\n // https://developer.mozilla.org/en-US/docs/Web/API/notification/maxActions\n const { actions } = notificationPayloadInternal;\n const { maxActions } = Notification;\n if (actions && maxActions && actions.length > maxActions) {\n console.warn(\n `This browser only supports ${maxActions} actions. The remaining actions will not be displayed.`\n );\n }\n\n return self.registration.showNotification(\n /* title= */ notificationPayloadInternal.title ?? '',\n notificationPayloadInternal\n );\n}\n\nfunction getLink(payload: MessagePayloadInternal): string | null {\n // eslint-disable-next-line camelcase\n const link = payload.fcmOptions?.link ?? payload.notification?.click_action;\n if (link) {\n return link;\n }\n\n if (isConsoleMessage(payload.data)) {\n // Notification created in the Firebase Console. Redirect to origin.\n return self.location.origin;\n } else {\n return null;\n }\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ERROR_FACTORY, ErrorCode } from '../util/errors';\nimport { FirebaseApp, FirebaseOptions } from '@firebase/app';\n\nimport { AppConfig } from '../interfaces/app-config';\nimport { FirebaseError } from '@firebase/util';\n\nexport function extractAppConfig(app: FirebaseApp): AppConfig {\n if (!app || !app.options) {\n throw getMissingValueError('App Configuration Object');\n }\n\n if (!app.name) {\n throw getMissingValueError('App Name');\n }\n\n // Required app config keys\n const configKeys: ReadonlyArray = [\n 'projectId',\n 'apiKey',\n 'appId',\n 'messagingSenderId'\n ];\n\n const { options } = app;\n for (const keyName of configKeys) {\n if (!options[keyName]) {\n throw getMissingValueError(keyName);\n }\n }\n\n return {\n appName: app.name,\n projectId: options.projectId!,\n apiKey: options.apiKey!,\n appId: options.appId!,\n senderId: options.messagingSenderId!\n };\n}\n\nfunction getMissingValueError(valueName: string): FirebaseError {\n return ERROR_FACTORY.create(ErrorCode.MISSING_APP_CONFIG_VALUES, {\n valueName\n });\n}\n", "/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { FirebaseApp, _FirebaseService } from '@firebase/app';\nimport { MessagePayload, NextFn, Observer } from './interfaces/public-types';\n\nimport { FirebaseAnalyticsInternalName } from '@firebase/analytics-interop-types';\nimport { FirebaseInternalDependencies } from './interfaces/internal-dependencies';\nimport { LogEvent } from './interfaces/logging-types';\nimport { Provider } from '@firebase/component';\nimport { _FirebaseInstallationsInternal } from '@firebase/installations';\nimport { extractAppConfig } from './helpers/extract-app-config';\n\nexport class MessagingService implements _FirebaseService {\n readonly app!: FirebaseApp;\n readonly firebaseDependencies!: FirebaseInternalDependencies;\n\n swRegistration?: ServiceWorkerRegistration;\n vapidKey?: string;\n // logging is only done with end user consent. Default to false.\n deliveryMetricsExportedToBigQueryEnabled: boolean = false;\n\n onBackgroundMessageHandler:\n | NextFn\n | Observer\n | null = null;\n\n onMessageHandler: NextFn | Observer | null =\n null;\n\n logEvents: LogEvent[] = [];\n isLogServiceStarted: boolean = false;\n\n constructor(\n app: FirebaseApp,\n installations: _FirebaseInstallationsInternal,\n analyticsProvider: Provider\n ) {\n const appConfig = extractAppConfig(app);\n\n this.firebaseDependencies = {\n app,\n appConfig,\n installations,\n analyticsProvider\n };\n }\n\n _delete(): Promise {\n return Promise.resolve();\n }\n}\n", "/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n Component,\n ComponentContainer,\n ComponentType,\n InstanceFactory\n} from '@firebase/component';\nimport {\n onNotificationClick,\n onPush,\n onSubChange\n} from '../listeners/sw-listeners';\n\nimport { GetTokenOptions } from '../interfaces/public-types';\nimport { MessagingInternal } from '@firebase/messaging-interop-types';\nimport { MessagingService } from '../messaging-service';\nimport { ServiceWorkerGlobalScope } from '../util/sw-types';\nimport { _registerComponent, registerVersion } from '@firebase/app';\nimport { getToken } from '../api/getToken';\nimport { messageEventListener } from '../listeners/window-listener';\n\nimport { name, version } from '../../package.json';\n\nconst WindowMessagingFactory: InstanceFactory<'messaging'> = (\n container: ComponentContainer\n) => {\n const messaging = new MessagingService(\n container.getProvider('app').getImmediate(),\n container.getProvider('installations-internal').getImmediate(),\n container.getProvider('analytics-internal')\n );\n\n navigator.serviceWorker.addEventListener('message', e =>\n messageEventListener(messaging as MessagingService, e)\n );\n\n return messaging;\n};\n\nconst WindowMessagingInternalFactory: InstanceFactory<'messaging-internal'> = (\n container: ComponentContainer\n) => {\n const messaging = container\n .getProvider('messaging')\n .getImmediate() as MessagingService;\n\n const messagingInternal: MessagingInternal = {\n getToken: (options?: GetTokenOptions) => getToken(messaging, options)\n };\n\n return messagingInternal;\n};\n\ndeclare const self: ServiceWorkerGlobalScope;\nconst SwMessagingFactory: InstanceFactory<'messaging'> = (\n container: ComponentContainer\n) => {\n const messaging = new MessagingService(\n container.getProvider('app').getImmediate(),\n container.getProvider('installations-internal').getImmediate(),\n container.getProvider('analytics-internal')\n );\n\n self.addEventListener('push', e => {\n e.waitUntil(onPush(e, messaging as MessagingService));\n });\n self.addEventListener('pushsubscriptionchange', e => {\n e.waitUntil(onSubChange(e, messaging as MessagingService));\n });\n self.addEventListener('notificationclick', e => {\n e.waitUntil(onNotificationClick(e));\n });\n\n return messaging;\n};\n\nexport function registerMessagingInWindow(): void {\n _registerComponent(\n new Component('messaging', WindowMessagingFactory, ComponentType.PUBLIC)\n );\n\n _registerComponent(\n new Component(\n 'messaging-internal',\n WindowMessagingInternalFactory,\n ComponentType.PRIVATE\n )\n );\n\n registerVersion(name, version);\n // BUILD_TARGET will be replaced by values like esm5, esm2017, cjs5, etc during the compilation\n registerVersion(name, version, '__BUILD_TARGET__');\n}\n\n/**\n * The messaging instance registered in sw is named differently than that of in client. This is\n * because both `registerMessagingInWindow` and `registerMessagingInSw` would be called in\n * `messaging-compat` and component with the same name can only be registered once.\n */\nexport function registerMessagingInSw(): void {\n _registerComponent(\n new Component('messaging-sw', SwMessagingFactory, ComponentType.PUBLIC)\n );\n}\n", "/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n areCookiesEnabled,\n isIndexedDBAvailable,\n validateIndexedDBOpenable\n} from '@firebase/util';\n\n/**\n * Checks if all required APIs exist in the browser.\n * @returns a Promise that resolves to a boolean.\n *\n * @public\n */\nexport async function isWindowSupported(): Promise {\n try {\n // This throws if open() is unsupported, so adding it to the conditional\n // statement below can cause an uncaught error.\n await validateIndexedDBOpenable();\n } catch (e) {\n return false;\n }\n // firebase-js-sdk/issues/2393 reveals that idb#open in Safari iframe and Firefox private browsing\n // might be prohibited to run. In these contexts, an error would be thrown during the messaging\n // instantiating phase, informing the developers to import/call isSupported for special handling.\n return (\n typeof window !== 'undefined' &&\n isIndexedDBAvailable() &&\n areCookiesEnabled() &&\n 'serviceWorker' in navigator &&\n 'PushManager' in window &&\n 'Notification' in window &&\n 'fetch' in window &&\n ServiceWorkerRegistration.prototype.hasOwnProperty('showNotification') &&\n PushSubscription.prototype.hasOwnProperty('getKey')\n );\n}\n\n/**\n * Checks whether all required APIs exist within SW Context\n * @returns a Promise that resolves to a boolean.\n *\n * @public\n */\nexport async function isSwSupported(): Promise {\n // firebase-js-sdk/issues/2393 reveals that idb#open in Safari iframe and Firefox private browsing\n // might be prohibited to run. In these contexts, an error would be thrown during the messaging\n // instantiating phase, informing the developers to import/call isSupported for special handling.\n return (\n isIndexedDBAvailable() &&\n (await validateIndexedDBOpenable()) &&\n 'PushManager' in self &&\n 'Notification' in self &&\n ServiceWorkerRegistration.prototype.hasOwnProperty('showNotification') &&\n PushSubscription.prototype.hasOwnProperty('getKey')\n );\n}\n", "/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ERROR_FACTORY, ErrorCode } from '../util/errors';\n\nimport {\n MessagePayload,\n NextFn,\n Observer,\n Unsubscribe\n} from '../interfaces/public-types';\nimport { MessagingService } from '../messaging-service';\n\nexport function onBackgroundMessage(\n messaging: MessagingService,\n nextOrObserver: NextFn | Observer\n): Unsubscribe {\n if (self.document !== undefined) {\n throw ERROR_FACTORY.create(ErrorCode.AVAILABLE_IN_SW);\n }\n\n messaging.onBackgroundMessageHandler = nextOrObserver;\n\n return () => {\n messaging.onBackgroundMessageHandler = null;\n };\n}\n", "/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Messaging } from '../interfaces/public-types';\nimport { MessagingService } from '../messaging-service';\n\nexport function _setDeliveryMetricsExportedToBigQueryEnabled(\n messaging: Messaging,\n enable: boolean\n): void {\n (messaging as MessagingService).deliveryMetricsExportedToBigQueryEnabled =\n enable;\n}\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ERROR_FACTORY, ErrorCode } from './util/errors';\nimport { FirebaseApp, _getProvider, getApp } from '@firebase/app';\nimport {\n GetTokenOptions,\n MessagePayload,\n Messaging\n} from './interfaces/public-types';\nimport {\n NextFn,\n Observer,\n Unsubscribe,\n getModularInstance\n} from '@firebase/util';\nimport { isSwSupported, isWindowSupported } from './api/isSupported';\n\nimport { MessagingService } from './messaging-service';\nimport { deleteToken as _deleteToken } from './api/deleteToken';\nimport { getToken as _getToken } from './api/getToken';\nimport { onBackgroundMessage as _onBackgroundMessage } from './api/onBackgroundMessage';\nimport { onMessage as _onMessage } from './api/onMessage';\nimport { _setDeliveryMetricsExportedToBigQueryEnabled } from './api/setDeliveryMetricsExportedToBigQueryEnabled';\n\n/**\n * Retrieves a Firebase Cloud Messaging instance.\n *\n * @returns The Firebase Cloud Messaging instance associated with the provided firebase app.\n *\n * @public\n */\nexport function getMessagingInWindow(app: FirebaseApp = getApp()): Messaging {\n // Conscious decision to make this async check non-blocking during the messaging instance\n // initialization phase for performance consideration. An error would be thrown latter for\n // developer's information. Developers can then choose to import and call `isSupported` for\n // special handling.\n isWindowSupported().then(\n isSupported => {\n // If `isWindowSupported()` resolved, but returned false.\n if (!isSupported) {\n throw ERROR_FACTORY.create(ErrorCode.UNSUPPORTED_BROWSER);\n }\n },\n _ => {\n // If `isWindowSupported()` rejected.\n throw ERROR_FACTORY.create(ErrorCode.INDEXED_DB_UNSUPPORTED);\n }\n );\n return _getProvider(getModularInstance(app), 'messaging').getImmediate();\n}\n\n/**\n * Retrieves a Firebase Cloud Messaging instance.\n *\n * @returns The Firebase Cloud Messaging instance associated with the provided firebase app.\n *\n * @public\n */\nexport function getMessagingInSw(app: FirebaseApp = getApp()): Messaging {\n // Conscious decision to make this async check non-blocking during the messaging instance\n // initialization phase for performance consideration. An error would be thrown latter for\n // developer's information. Developers can then choose to import and call `isSupported` for\n // special handling.\n isSwSupported().then(\n isSupported => {\n // If `isSwSupported()` resolved, but returned false.\n if (!isSupported) {\n throw ERROR_FACTORY.create(ErrorCode.UNSUPPORTED_BROWSER);\n }\n },\n _ => {\n // If `isSwSupported()` rejected.\n throw ERROR_FACTORY.create(ErrorCode.INDEXED_DB_UNSUPPORTED);\n }\n );\n return _getProvider(getModularInstance(app), 'messaging-sw').getImmediate();\n}\n\n/**\n * Subscribes the {@link Messaging} instance to push notifications. Returns an Firebase Cloud\n * Messaging registration token that can be used to send push messages to that {@link Messaging}\n * instance.\n *\n * If a notification permission isn't already granted, this method asks the user for permission. The\n * returned promise rejects if the user does not allow the app to show notifications.\n *\n * @param messaging - The {@link Messaging} instance.\n * @param options - Provides an optional vapid key and an optinoal service worker registration\n *\n * @returns The promise resolves with an FCM registration token.\n *\n * @public\n */\nexport async function getToken(\n messaging: Messaging,\n options?: GetTokenOptions\n): Promise {\n messaging = getModularInstance(messaging);\n return _getToken(messaging as MessagingService, options);\n}\n\n/**\n * Deletes the registration token associated with this {@link Messaging} instance and unsubscribes\n * the {@link Messaging} instance from the push subscription.\n *\n * @param messaging - The {@link Messaging} instance.\n *\n * @returns The promise resolves when the token has been successfully deleted.\n *\n * @public\n */\nexport function deleteToken(messaging: Messaging): Promise {\n messaging = getModularInstance(messaging);\n return _deleteToken(messaging as MessagingService);\n}\n\n/**\n * When a push message is received and the user is currently on a page for your origin, the\n * message is passed to the page and an `onMessage()` event is dispatched with the payload of\n * the push message.\n *\n *\n * @param messaging - The {@link Messaging} instance.\n * @param nextOrObserver - This function, or observer object with `next` defined,\n * is called when a message is received and the user is currently viewing your page.\n * @returns To stop listening for messages execute this returned function.\n *\n * @public\n */\nexport function onMessage(\n messaging: Messaging,\n nextOrObserver: NextFn | Observer\n): Unsubscribe {\n messaging = getModularInstance(messaging);\n return _onMessage(messaging as MessagingService, nextOrObserver);\n}\n\n/**\n * Called when a message is received while the app is in the background. An app is considered to be\n * in the background if no active window is displayed.\n *\n * @param messaging - The {@link Messaging} instance.\n * @param nextOrObserver - This function, or observer object with `next` defined, is called when a\n * message is received and the app is currently in the background.\n *\n * @returns To stop listening for messages execute this returned function\n *\n * @public\n */\nexport function onBackgroundMessage(\n messaging: Messaging,\n nextOrObserver: NextFn | Observer\n): Unsubscribe {\n messaging = getModularInstance(messaging);\n return _onBackgroundMessage(messaging as MessagingService, nextOrObserver);\n}\n\n/**\n * Enables or disables Firebase Cloud Messaging message delivery metrics export to BigQuery. By\n * default, message delivery metrics are not exported to BigQuery. Use this method to enable or\n * disable the export at runtime.\n *\n * @param messaging - The `FirebaseMessaging` instance.\n * @param enable - Whether Firebase Cloud Messaging should export message delivery metrics to\n * BigQuery.\n *\n * @public\n */\nexport function experimentalSetDeliveryMetricsExportedToBigQueryEnabled(\n messaging: Messaging,\n enable: boolean\n): void {\n messaging = getModularInstance(messaging);\n return _setDeliveryMetricsExportedToBigQueryEnabled(messaging, enable);\n}\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport '@firebase/installations';\n\nimport { Messaging } from './interfaces/public-types';\nimport { registerMessagingInSw } from './helpers/register';\n\nexport * from './interfaces/public-types';\nexport {\n onBackgroundMessage,\n getMessagingInSw as getMessaging,\n experimentalSetDeliveryMetricsExportedToBigQueryEnabled\n} from './api';\nexport { isSwSupported as isSupported } from './api/isSupported';\n\ndeclare module '@firebase/component' {\n interface NameServiceMapping {\n 'messaging-sw': Messaging;\n }\n}\n\nregisterMessagingInSw();\n", "import { initializeApp } from 'firebase/app';\nimport {\n experimentalSetDeliveryMetricsExportedToBigQueryEnabled,\n getMessaging,\n isSupported,\n onBackgroundMessage,\n} from 'firebase/messaging/sw';\n\nself.addEventListener('install', (event) => {\n console.log(self);\n console.log(event);\n});\n\nconst app = initializeApp({\n apiKey: 'AIzaSyAgUhHU8wSJgO5MVNy95tMT07NEjzMOfz0',\n authDomain: 'react-native-firebase-testing.firebaseapp.com',\n databaseURL: 'https://react-native-firebase-testing.firebaseio.com',\n projectId: 'react-native-firebase-testing',\n storageBucket: 'react-native-firebase-testing.appspot.com',\n messagingSenderId: '448618578101',\n appId: '1:448618578101:web:ecaffe2bc4511738',\n});\n\nisSupported().then((isSupported) => {\n if (isSupported) {\n const messaging = getMessaging(app);\n\n experimentalSetDeliveryMetricsExportedToBigQueryEnabled(messaging, true);\n\n console.log('experimental working');\n\n onBackgroundMessage(messaging, ({ notification: notification }) => {\n const { title, body, image } = notification ?? {};\n\n if (!title) {\n return;\n }\n\n self.registration.showNotification(title, {\n body,\n icon: image || '/assets/icons/icon-72x72.png',\n });\n });\n }\n});\n"], - "mappings": "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", + "sourcesContent": ["/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * @fileoverview Firebase constants. Some of these (@defines) can be overridden at compile-time.\n */\n\nexport const CONSTANTS = {\n /**\n * @define {boolean} Whether this is the client Node.js SDK.\n */\n NODE_CLIENT: false,\n /**\n * @define {boolean} Whether this is the Admin Node.js SDK.\n */\n NODE_ADMIN: false,\n\n /**\n * Firebase SDK Version\n */\n SDK_VERSION: '${JSCORE_VERSION}'\n};\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { CONSTANTS } from './constants';\n\n/**\n * Throws an error if the provided assertion is falsy\n */\nexport const assert = function (assertion: unknown, message: string): void {\n if (!assertion) {\n throw assertionError(message);\n }\n};\n\n/**\n * Returns an Error object suitable for throwing.\n */\nexport const assertionError = function (message: string): Error {\n return new Error(\n 'Firebase Database (' +\n CONSTANTS.SDK_VERSION +\n ') INTERNAL ASSERT FAILED: ' +\n message\n );\n};\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nconst stringToByteArray = function (str: string): number[] {\n // TODO(user): Use native implementations if/when available\n const out: number[] = [];\n let p = 0;\n for (let i = 0; i < str.length; i++) {\n let c = str.charCodeAt(i);\n if (c < 128) {\n out[p++] = c;\n } else if (c < 2048) {\n out[p++] = (c >> 6) | 192;\n out[p++] = (c & 63) | 128;\n } else if (\n (c & 0xfc00) === 0xd800 &&\n i + 1 < str.length &&\n (str.charCodeAt(i + 1) & 0xfc00) === 0xdc00\n ) {\n // Surrogate Pair\n c = 0x10000 + ((c & 0x03ff) << 10) + (str.charCodeAt(++i) & 0x03ff);\n out[p++] = (c >> 18) | 240;\n out[p++] = ((c >> 12) & 63) | 128;\n out[p++] = ((c >> 6) & 63) | 128;\n out[p++] = (c & 63) | 128;\n } else {\n out[p++] = (c >> 12) | 224;\n out[p++] = ((c >> 6) & 63) | 128;\n out[p++] = (c & 63) | 128;\n }\n }\n return out;\n};\n\n/**\n * Turns an array of numbers into the string given by the concatenation of the\n * characters to which the numbers correspond.\n * @param bytes Array of numbers representing characters.\n * @return Stringification of the array.\n */\nconst byteArrayToString = function (bytes: number[]): string {\n // TODO(user): Use native implementations if/when available\n const out: string[] = [];\n let pos = 0,\n c = 0;\n while (pos < bytes.length) {\n const c1 = bytes[pos++];\n if (c1 < 128) {\n out[c++] = String.fromCharCode(c1);\n } else if (c1 > 191 && c1 < 224) {\n const c2 = bytes[pos++];\n out[c++] = String.fromCharCode(((c1 & 31) << 6) | (c2 & 63));\n } else if (c1 > 239 && c1 < 365) {\n // Surrogate Pair\n const c2 = bytes[pos++];\n const c3 = bytes[pos++];\n const c4 = bytes[pos++];\n const u =\n (((c1 & 7) << 18) | ((c2 & 63) << 12) | ((c3 & 63) << 6) | (c4 & 63)) -\n 0x10000;\n out[c++] = String.fromCharCode(0xd800 + (u >> 10));\n out[c++] = String.fromCharCode(0xdc00 + (u & 1023));\n } else {\n const c2 = bytes[pos++];\n const c3 = bytes[pos++];\n out[c++] = String.fromCharCode(\n ((c1 & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)\n );\n }\n }\n return out.join('');\n};\n\ninterface Base64 {\n byteToCharMap_: { [key: number]: string } | null;\n charToByteMap_: { [key: string]: number } | null;\n byteToCharMapWebSafe_: { [key: number]: string } | null;\n charToByteMapWebSafe_: { [key: string]: number } | null;\n ENCODED_VALS_BASE: string;\n readonly ENCODED_VALS: string;\n readonly ENCODED_VALS_WEBSAFE: string;\n HAS_NATIVE_SUPPORT: boolean;\n encodeByteArray(input: number[] | Uint8Array, webSafe?: boolean): string;\n encodeString(input: string, webSafe?: boolean): string;\n decodeString(input: string, webSafe: boolean): string;\n decodeStringToByteArray(input: string, webSafe: boolean): number[];\n init_(): void;\n}\n\n// We define it as an object literal instead of a class because a class compiled down to es5 can't\n// be treeshaked. https://github.com/rollup/rollup/issues/1691\n// Static lookup maps, lazily populated by init_()\nexport const base64: Base64 = {\n /**\n * Maps bytes to characters.\n */\n byteToCharMap_: null,\n\n /**\n * Maps characters to bytes.\n */\n charToByteMap_: null,\n\n /**\n * Maps bytes to websafe characters.\n * @private\n */\n byteToCharMapWebSafe_: null,\n\n /**\n * Maps websafe characters to bytes.\n * @private\n */\n charToByteMapWebSafe_: null,\n\n /**\n * Our default alphabet, shared between\n * ENCODED_VALS and ENCODED_VALS_WEBSAFE\n */\n ENCODED_VALS_BASE:\n 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + 'abcdefghijklmnopqrstuvwxyz' + '0123456789',\n\n /**\n * Our default alphabet. Value 64 (=) is special; it means \"nothing.\"\n */\n get ENCODED_VALS() {\n return this.ENCODED_VALS_BASE + '+/=';\n },\n\n /**\n * Our websafe alphabet.\n */\n get ENCODED_VALS_WEBSAFE() {\n return this.ENCODED_VALS_BASE + '-_.';\n },\n\n /**\n * Whether this browser supports the atob and btoa functions. This extension\n * started at Mozilla but is now implemented by many browsers. We use the\n * ASSUME_* variables to avoid pulling in the full useragent detection library\n * but still allowing the standard per-browser compilations.\n *\n */\n HAS_NATIVE_SUPPORT: typeof atob === 'function',\n\n /**\n * Base64-encode an array of bytes.\n *\n * @param input An array of bytes (numbers with\n * value in [0, 255]) to encode.\n * @param webSafe Boolean indicating we should use the\n * alternative alphabet.\n * @return The base64 encoded string.\n */\n encodeByteArray(input: number[] | Uint8Array, webSafe?: boolean): string {\n if (!Array.isArray(input)) {\n throw Error('encodeByteArray takes an array as a parameter');\n }\n\n this.init_();\n\n const byteToCharMap = webSafe\n ? this.byteToCharMapWebSafe_!\n : this.byteToCharMap_!;\n\n const output = [];\n\n for (let i = 0; i < input.length; i += 3) {\n const byte1 = input[i];\n const haveByte2 = i + 1 < input.length;\n const byte2 = haveByte2 ? input[i + 1] : 0;\n const haveByte3 = i + 2 < input.length;\n const byte3 = haveByte3 ? input[i + 2] : 0;\n\n const outByte1 = byte1 >> 2;\n const outByte2 = ((byte1 & 0x03) << 4) | (byte2 >> 4);\n let outByte3 = ((byte2 & 0x0f) << 2) | (byte3 >> 6);\n let outByte4 = byte3 & 0x3f;\n\n if (!haveByte3) {\n outByte4 = 64;\n\n if (!haveByte2) {\n outByte3 = 64;\n }\n }\n\n output.push(\n byteToCharMap[outByte1],\n byteToCharMap[outByte2],\n byteToCharMap[outByte3],\n byteToCharMap[outByte4]\n );\n }\n\n return output.join('');\n },\n\n /**\n * Base64-encode a string.\n *\n * @param input A string to encode.\n * @param webSafe If true, we should use the\n * alternative alphabet.\n * @return The base64 encoded string.\n */\n encodeString(input: string, webSafe?: boolean): string {\n // Shortcut for Mozilla browsers that implement\n // a native base64 encoder in the form of \"btoa/atob\"\n if (this.HAS_NATIVE_SUPPORT && !webSafe) {\n return btoa(input);\n }\n return this.encodeByteArray(stringToByteArray(input), webSafe);\n },\n\n /**\n * Base64-decode a string.\n *\n * @param input to decode.\n * @param webSafe True if we should use the\n * alternative alphabet.\n * @return string representing the decoded value.\n */\n decodeString(input: string, webSafe: boolean): string {\n // Shortcut for Mozilla browsers that implement\n // a native base64 encoder in the form of \"btoa/atob\"\n if (this.HAS_NATIVE_SUPPORT && !webSafe) {\n return atob(input);\n }\n return byteArrayToString(this.decodeStringToByteArray(input, webSafe));\n },\n\n /**\n * Base64-decode a string.\n *\n * In base-64 decoding, groups of four characters are converted into three\n * bytes. If the encoder did not apply padding, the input length may not\n * be a multiple of 4.\n *\n * In this case, the last group will have fewer than 4 characters, and\n * padding will be inferred. If the group has one or two characters, it decodes\n * to one byte. If the group has three characters, it decodes to two bytes.\n *\n * @param input Input to decode.\n * @param webSafe True if we should use the web-safe alphabet.\n * @return bytes representing the decoded value.\n */\n decodeStringToByteArray(input: string, webSafe: boolean): number[] {\n this.init_();\n\n const charToByteMap = webSafe\n ? this.charToByteMapWebSafe_!\n : this.charToByteMap_!;\n\n const output: number[] = [];\n\n for (let i = 0; i < input.length; ) {\n const byte1 = charToByteMap[input.charAt(i++)];\n\n const haveByte2 = i < input.length;\n const byte2 = haveByte2 ? charToByteMap[input.charAt(i)] : 0;\n ++i;\n\n const haveByte3 = i < input.length;\n const byte3 = haveByte3 ? charToByteMap[input.charAt(i)] : 64;\n ++i;\n\n const haveByte4 = i < input.length;\n const byte4 = haveByte4 ? charToByteMap[input.charAt(i)] : 64;\n ++i;\n\n if (byte1 == null || byte2 == null || byte3 == null || byte4 == null) {\n throw Error();\n }\n\n const outByte1 = (byte1 << 2) | (byte2 >> 4);\n output.push(outByte1);\n\n if (byte3 !== 64) {\n const outByte2 = ((byte2 << 4) & 0xf0) | (byte3 >> 2);\n output.push(outByte2);\n\n if (byte4 !== 64) {\n const outByte3 = ((byte3 << 6) & 0xc0) | byte4;\n output.push(outByte3);\n }\n }\n }\n\n return output;\n },\n\n /**\n * Lazy static initialization function. Called before\n * accessing any of the static map variables.\n * @private\n */\n init_() {\n if (!this.byteToCharMap_) {\n this.byteToCharMap_ = {};\n this.charToByteMap_ = {};\n this.byteToCharMapWebSafe_ = {};\n this.charToByteMapWebSafe_ = {};\n\n // We want quick mappings back and forth, so we precompute two maps.\n for (let i = 0; i < this.ENCODED_VALS.length; i++) {\n this.byteToCharMap_[i] = this.ENCODED_VALS.charAt(i);\n this.charToByteMap_[this.byteToCharMap_[i]] = i;\n this.byteToCharMapWebSafe_[i] = this.ENCODED_VALS_WEBSAFE.charAt(i);\n this.charToByteMapWebSafe_[this.byteToCharMapWebSafe_[i]] = i;\n\n // Be forgiving when decoding and correctly decode both encodings.\n if (i >= this.ENCODED_VALS_BASE.length) {\n this.charToByteMap_[this.ENCODED_VALS_WEBSAFE.charAt(i)] = i;\n this.charToByteMapWebSafe_[this.ENCODED_VALS.charAt(i)] = i;\n }\n }\n }\n }\n};\n\n/**\n * URL-safe base64 encoding\n */\nexport const base64Encode = function (str: string): string {\n const utf8Bytes = stringToByteArray(str);\n return base64.encodeByteArray(utf8Bytes, true);\n};\n\n/**\n * URL-safe base64 encoding (without \".\" padding in the end).\n * e.g. Used in JSON Web Token (JWT) parts.\n */\nexport const base64urlEncodeWithoutPadding = function (str: string): string {\n // Use base64url encoding and remove padding in the end (dot characters).\n return base64Encode(str).replace(/\\./g, '');\n};\n\n/**\n * URL-safe base64 decoding\n *\n * NOTE: DO NOT use the global atob() function - it does NOT support the\n * base64Url variant encoding.\n *\n * @param str To be decoded\n * @return Decoded result, if possible\n */\nexport const base64Decode = function (str: string): string | null {\n try {\n return base64.decodeString(str, true);\n } catch (e) {\n console.error('base64Decode failed: ', e);\n }\n return null;\n};\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Do a deep-copy of basic JavaScript Objects or Arrays.\n */\nexport function deepCopy(value: T): T {\n return deepExtend(undefined, value) as T;\n}\n\n/**\n * Copy properties from source to target (recursively allows extension\n * of Objects and Arrays). Scalar values in the target are over-written.\n * If target is undefined, an object of the appropriate type will be created\n * (and returned).\n *\n * We recursively copy all child properties of plain Objects in the source- so\n * that namespace- like dictionaries are merged.\n *\n * Note that the target can be a function, in which case the properties in\n * the source Object are copied onto it as static properties of the Function.\n *\n * Note: we don't merge __proto__ to prevent prototype pollution\n */\nexport function deepExtend(target: unknown, source: unknown): unknown {\n if (!(source instanceof Object)) {\n return source;\n }\n\n switch (source.constructor) {\n case Date:\n // Treat Dates like scalars; if the target date object had any child\n // properties - they will be lost!\n const dateValue = source as Date;\n return new Date(dateValue.getTime());\n\n case Object:\n if (target === undefined) {\n target = {};\n }\n break;\n case Array:\n // Always copy the array source and overwrite the target.\n target = [];\n break;\n\n default:\n // Not a plain Object - treat it as a scalar.\n return source;\n }\n\n for (const prop in source) {\n // use isValidKey to guard against prototype pollution. See https://snyk.io/vuln/SNYK-JS-LODASH-450202\n if (!source.hasOwnProperty(prop) || !isValidKey(prop)) {\n continue;\n }\n (target as Record)[prop] = deepExtend(\n (target as Record)[prop],\n (source as Record)[prop]\n );\n }\n\n return target;\n}\n\nfunction isValidKey(key: string): boolean {\n return key !== '__proto__';\n}\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport class Deferred {\n promise: Promise;\n reject: (value?: unknown) => void = () => {};\n resolve: (value?: unknown) => void = () => {};\n constructor() {\n this.promise = new Promise((resolve, reject) => {\n this.resolve = resolve as (value?: unknown) => void;\n this.reject = reject as (value?: unknown) => void;\n });\n }\n\n /**\n * Our API internals are not promiseified and cannot because our callback APIs have subtle expectations around\n * invoking promises inline, which Promises are forbidden to do. This method accepts an optional node-style callback\n * and returns a node-style callback which will resolve or reject the Deferred's promise.\n */\n wrapCallback(\n callback?: (error?: unknown, value?: unknown) => void\n ): (error: unknown, value?: unknown) => void {\n return (error, value?) => {\n if (error) {\n this.reject(error);\n } else {\n this.resolve(value);\n }\n if (typeof callback === 'function') {\n // Attaching noop handler just in case developer wasn't expecting\n // promises\n this.promise.catch(() => {});\n\n // Some of our callbacks don't expect a value and our own tests\n // assert that the parameter length is 1\n if (callback.length === 1) {\n callback(error);\n } else {\n callback(error, value);\n }\n }\n };\n }\n}\n", "/**\n * @license\n * Copyright 2021 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { base64urlEncodeWithoutPadding } from './crypt';\n\n// Firebase Auth tokens contain snake_case claims following the JWT standard / convention.\n/* eslint-disable camelcase */\n\nexport type FirebaseSignInProvider =\n | 'custom'\n | 'email'\n | 'password'\n | 'phone'\n | 'anonymous'\n | 'google.com'\n | 'facebook.com'\n | 'github.com'\n | 'twitter.com'\n | 'microsoft.com'\n | 'apple.com';\n\ninterface FirebaseIdToken {\n // Always set to https://securetoken.google.com/PROJECT_ID\n iss: string;\n\n // Always set to PROJECT_ID\n aud: string;\n\n // The user's unique ID\n sub: string;\n\n // The token issue time, in seconds since epoch\n iat: number;\n\n // The token expiry time, normally 'iat' + 3600\n exp: number;\n\n // The user's unique ID. Must be equal to 'sub'\n user_id: string;\n\n // The time the user authenticated, normally 'iat'\n auth_time: number;\n\n // The sign in provider, only set when the provider is 'anonymous'\n provider_id?: 'anonymous';\n\n // The user's primary email\n email?: string;\n\n // The user's email verification status\n email_verified?: boolean;\n\n // The user's primary phone number\n phone_number?: string;\n\n // The user's display name\n name?: string;\n\n // The user's profile photo URL\n picture?: string;\n\n // Information on all identities linked to this user\n firebase: {\n // The primary sign-in provider\n sign_in_provider: FirebaseSignInProvider;\n\n // A map of providers to the user's list of unique identifiers from\n // each provider\n identities?: { [provider in FirebaseSignInProvider]?: string[] };\n };\n\n // Custom claims set by the developer\n [claim: string]: unknown;\n\n uid?: never; // Try to catch a common mistake of \"uid\" (should be \"sub\" instead).\n}\n\nexport type EmulatorMockTokenOptions = ({ user_id: string } | { sub: string }) &\n Partial;\n\nexport function createMockUserToken(\n token: EmulatorMockTokenOptions,\n projectId?: string\n): string {\n if (token.uid) {\n throw new Error(\n 'The \"uid\" field is no longer supported by mockUserToken. Please use \"sub\" instead for Firebase Auth User ID.'\n );\n }\n // Unsecured JWTs use \"none\" as the algorithm.\n const header = {\n alg: 'none',\n type: 'JWT'\n };\n\n const project = projectId || 'demo-project';\n const iat = token.iat || 0;\n const sub = token.sub || token.user_id;\n if (!sub) {\n throw new Error(\"mockUserToken must contain 'sub' or 'user_id' field!\");\n }\n\n const payload: FirebaseIdToken = {\n // Set all required fields to decent defaults\n iss: `https://securetoken.google.com/${project}`,\n aud: project,\n iat,\n exp: iat + 3600,\n auth_time: iat,\n sub,\n user_id: sub,\n firebase: {\n sign_in_provider: 'custom',\n identities: {}\n },\n\n // Override with user options\n ...token\n };\n\n // Unsecured JWTs use the empty string as a signature.\n const signature = '';\n return [\n base64urlEncodeWithoutPadding(JSON.stringify(header)),\n base64urlEncodeWithoutPadding(JSON.stringify(payload)),\n signature\n ].join('.');\n}\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { CONSTANTS } from './constants';\n\n/**\n * Returns navigator.userAgent string or '' if it's not defined.\n * @return user agent string\n */\nexport function getUA(): string {\n if (\n typeof navigator !== 'undefined' &&\n typeof navigator['userAgent'] === 'string'\n ) {\n return navigator['userAgent'];\n } else {\n return '';\n }\n}\n\n/**\n * Detect Cordova / PhoneGap / Ionic frameworks on a mobile device.\n *\n * Deliberately does not rely on checking `file://` URLs (as this fails PhoneGap\n * in the Ripple emulator) nor Cordova `onDeviceReady`, which would normally\n * wait for a callback.\n */\nexport function isMobileCordova(): boolean {\n return (\n typeof window !== 'undefined' &&\n // @ts-ignore Setting up an broadly applicable index signature for Window\n // just to deal with this case would probably be a bad idea.\n !!(window['cordova'] || window['phonegap'] || window['PhoneGap']) &&\n /ios|iphone|ipod|ipad|android|blackberry|iemobile/i.test(getUA())\n );\n}\n\n/**\n * Detect Node.js.\n *\n * @return true if Node.js environment is detected.\n */\n// Node detection logic from: https://github.com/iliakan/detect-node/\nexport function isNode(): boolean {\n try {\n return (\n Object.prototype.toString.call(global.process) === '[object process]'\n );\n } catch (e) {\n return false;\n }\n}\n\n/**\n * Detect Browser Environment\n */\nexport function isBrowser(): boolean {\n return typeof self === 'object' && self.self === self;\n}\n\n/**\n * Detect browser extensions (Chrome and Firefox at least).\n */\ninterface BrowserRuntime {\n id?: unknown;\n}\ndeclare const chrome: { runtime?: BrowserRuntime };\ndeclare const browser: { runtime?: BrowserRuntime };\nexport function isBrowserExtension(): boolean {\n const runtime =\n typeof chrome === 'object'\n ? chrome.runtime\n : typeof browser === 'object'\n ? browser.runtime\n : undefined;\n return typeof runtime === 'object' && runtime.id !== undefined;\n}\n\n/**\n * Detect React Native.\n *\n * @return true if ReactNative environment is detected.\n */\nexport function isReactNative(): boolean {\n return (\n typeof navigator === 'object' && navigator['product'] === 'ReactNative'\n );\n}\n\n/** Detects Electron apps. */\nexport function isElectron(): boolean {\n return getUA().indexOf('Electron/') >= 0;\n}\n\n/** Detects Internet Explorer. */\nexport function isIE(): boolean {\n const ua = getUA();\n return ua.indexOf('MSIE ') >= 0 || ua.indexOf('Trident/') >= 0;\n}\n\n/** Detects Universal Windows Platform apps. */\nexport function isUWP(): boolean {\n return getUA().indexOf('MSAppHost/') >= 0;\n}\n\n/**\n * Detect whether the current SDK build is the Node version.\n *\n * @return true if it's the Node SDK build.\n */\nexport function isNodeSdk(): boolean {\n return CONSTANTS.NODE_CLIENT === true || CONSTANTS.NODE_ADMIN === true;\n}\n\n/** Returns true if we are running in Safari. */\nexport function isSafari(): boolean {\n return (\n !isNode() &&\n navigator.userAgent.includes('Safari') &&\n !navigator.userAgent.includes('Chrome')\n );\n}\n\n/**\n * This method checks if indexedDB is supported by current browser/service worker context\n * @return true if indexedDB is supported by current browser/service worker context\n */\nexport function isIndexedDBAvailable(): boolean {\n return typeof indexedDB === 'object';\n}\n\n/**\n * This method validates browser/sw context for indexedDB by opening a dummy indexedDB database and reject\n * if errors occur during the database open operation.\n *\n * @throws exception if current browser/sw context can't run idb.open (ex: Safari iframe, Firefox\n * private browsing)\n */\nexport function validateIndexedDBOpenable(): Promise {\n return new Promise((resolve, reject) => {\n try {\n let preExist: boolean = true;\n const DB_CHECK_NAME =\n 'validate-browser-context-for-indexeddb-analytics-module';\n const request = self.indexedDB.open(DB_CHECK_NAME);\n request.onsuccess = () => {\n request.result.close();\n // delete database only when it doesn't pre-exist\n if (!preExist) {\n self.indexedDB.deleteDatabase(DB_CHECK_NAME);\n }\n resolve(true);\n };\n request.onupgradeneeded = () => {\n preExist = false;\n };\n\n request.onerror = () => {\n reject(request.error?.message || '');\n };\n } catch (error) {\n reject(error);\n }\n });\n}\n\n/**\n *\n * This method checks whether cookie is enabled within current browser\n * @return true if cookie is enabled within current browser\n */\nexport function areCookiesEnabled(): boolean {\n if (typeof navigator === 'undefined' || !navigator.cookieEnabled) {\n return false;\n }\n return true;\n}\n\n/**\n * Polyfill for `globalThis` object.\n * @returns the `globalThis` object for the given environment.\n */\nexport function getGlobal(): typeof globalThis {\n if (typeof self !== 'undefined') {\n return self;\n }\n if (typeof window !== 'undefined') {\n return window;\n }\n if (typeof global !== 'undefined') {\n return global;\n }\n throw new Error('Unable to locate global object.');\n}\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/**\n * @fileoverview Standardized Firebase Error.\n *\n * Usage:\n *\n * // Typescript string literals for type-safe codes\n * type Err =\n * 'unknown' |\n * 'object-not-found'\n * ;\n *\n * // Closure enum for type-safe error codes\n * // at-enum {string}\n * var Err = {\n * UNKNOWN: 'unknown',\n * OBJECT_NOT_FOUND: 'object-not-found',\n * }\n *\n * let errors: Map = {\n * 'generic-error': \"Unknown error\",\n * 'file-not-found': \"Could not find file: {$file}\",\n * };\n *\n * // Type-safe function - must pass a valid error code as param.\n * let error = new ErrorFactory('service', 'Service', errors);\n *\n * ...\n * throw error.create(Err.GENERIC);\n * ...\n * throw error.create(Err.FILE_NOT_FOUND, {'file': fileName});\n * ...\n * // Service: Could not file file: foo.txt (service/file-not-found).\n *\n * catch (e) {\n * assert(e.message === \"Could not find file: foo.txt.\");\n * if ((e as FirebaseError)?.code === 'service/file-not-found') {\n * console.log(\"Could not read file: \" + e['file']);\n * }\n * }\n */\n\nexport type ErrorMap = {\n readonly [K in ErrorCode]: string;\n};\n\nconst ERROR_NAME = 'FirebaseError';\n\nexport interface StringLike {\n toString(): string;\n}\n\nexport interface ErrorData {\n [key: string]: unknown;\n}\n\n// Based on code from:\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error#Custom_Error_Types\nexport class FirebaseError extends Error {\n /** The custom name for all FirebaseErrors. */\n readonly name: string = ERROR_NAME;\n\n constructor(\n /** The error code for this error. */\n readonly code: string,\n message: string,\n /** Custom data for this error. */\n public customData?: Record\n ) {\n super(message);\n\n // Fix For ES5\n // https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work\n Object.setPrototypeOf(this, FirebaseError.prototype);\n\n // Maintains proper stack trace for where our error was thrown.\n // Only available on V8.\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, ErrorFactory.prototype.create);\n }\n }\n}\n\nexport class ErrorFactory<\n ErrorCode extends string,\n ErrorParams extends { readonly [K in ErrorCode]?: ErrorData } = {}\n> {\n constructor(\n private readonly service: string,\n private readonly serviceName: string,\n private readonly errors: ErrorMap\n ) {}\n\n create(\n code: K,\n ...data: K extends keyof ErrorParams ? [ErrorParams[K]] : []\n ): FirebaseError {\n const customData = (data[0] as ErrorData) || {};\n const fullCode = `${this.service}/${code}`;\n const template = this.errors[code];\n\n const message = template ? replaceTemplate(template, customData) : 'Error';\n // Service Name: Error message (service/code).\n const fullMessage = `${this.serviceName}: ${message} (${fullCode}).`;\n\n const error = new FirebaseError(fullCode, fullMessage, customData);\n\n return error;\n }\n}\n\nfunction replaceTemplate(template: string, data: ErrorData): string {\n return template.replace(PATTERN, (_, key) => {\n const value = data[key];\n return value != null ? String(value) : `<${key}?>`;\n });\n}\n\nconst PATTERN = /\\{\\$([^}]+)}/g;\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Evaluates a JSON string into a javascript object.\n *\n * @param {string} str A string containing JSON.\n * @return {*} The javascript object representing the specified JSON.\n */\nexport function jsonEval(str: string): unknown {\n return JSON.parse(str);\n}\n\n/**\n * Returns JSON representing a javascript object.\n * @param {*} data Javascript object to be stringified.\n * @return {string} The JSON contents of the object.\n */\nexport function stringify(data: unknown): string {\n return JSON.stringify(data);\n}\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { base64Decode } from './crypt';\nimport { jsonEval } from './json';\n\ninterface Claims {\n [key: string]: {};\n}\n\ninterface DecodedToken {\n header: object;\n claims: Claims;\n data: object;\n signature: string;\n}\n\n/**\n * Decodes a Firebase auth. token into constituent parts.\n *\n * Notes:\n * - May return with invalid / incomplete claims if there's no native base64 decoding support.\n * - Doesn't check if the token is actually valid.\n */\nexport const decode = function (token: string): DecodedToken {\n let header = {},\n claims: Claims = {},\n data = {},\n signature = '';\n\n try {\n const parts = token.split('.');\n header = jsonEval(base64Decode(parts[0]) || '') as object;\n claims = jsonEval(base64Decode(parts[1]) || '') as Claims;\n signature = parts[2];\n data = claims['d'] || {};\n delete claims['d'];\n } catch (e) {}\n\n return {\n header,\n claims,\n data,\n signature\n };\n};\n\ninterface DecodedToken {\n header: object;\n claims: Claims;\n data: object;\n signature: string;\n}\n\n/**\n * Decodes a Firebase auth. token and checks the validity of its time-based claims. Will return true if the\n * token is within the time window authorized by the 'nbf' (not-before) and 'iat' (issued-at) claims.\n *\n * Notes:\n * - May return a false negative if there's no native base64 decoding support.\n * - Doesn't check if the token is actually valid.\n */\nexport const isValidTimestamp = function (token: string): boolean {\n const claims: Claims = decode(token).claims;\n const now: number = Math.floor(new Date().getTime() / 1000);\n let validSince: number = 0,\n validUntil: number = 0;\n\n if (typeof claims === 'object') {\n if (claims.hasOwnProperty('nbf')) {\n validSince = claims['nbf'] as number;\n } else if (claims.hasOwnProperty('iat')) {\n validSince = claims['iat'] as number;\n }\n\n if (claims.hasOwnProperty('exp')) {\n validUntil = claims['exp'] as number;\n } else {\n // token will expire after 24h by default\n validUntil = validSince + 86400;\n }\n }\n\n return (\n !!now &&\n !!validSince &&\n !!validUntil &&\n now >= validSince &&\n now <= validUntil\n );\n};\n\n/**\n * Decodes a Firebase auth. token and returns its issued at time if valid, null otherwise.\n *\n * Notes:\n * - May return null if there's no native base64 decoding support.\n * - Doesn't check if the token is actually valid.\n */\nexport const issuedAtTime = function (token: string): number | null {\n const claims: Claims = decode(token).claims;\n if (typeof claims === 'object' && claims.hasOwnProperty('iat')) {\n return claims['iat'] as number;\n }\n return null;\n};\n\n/**\n * Decodes a Firebase auth. token and checks the validity of its format. Expects a valid issued-at time.\n *\n * Notes:\n * - May return a false negative if there's no native base64 decoding support.\n * - Doesn't check if the token is actually valid.\n */\nexport const isValidFormat = function (token: string): boolean {\n const decoded = decode(token),\n claims = decoded.claims;\n\n return !!claims && typeof claims === 'object' && claims.hasOwnProperty('iat');\n};\n\n/**\n * Attempts to peer into an auth token and determine if it's an admin auth token by looking at the claims portion.\n *\n * Notes:\n * - May return a false negative if there's no native base64 decoding support.\n * - Doesn't check if the token is actually valid.\n */\nexport const isAdmin = function (token: string): boolean {\n const claims: Claims = decode(token).claims;\n return typeof claims === 'object' && claims['admin'] === true;\n};\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport function contains(obj: T, key: string): boolean {\n return Object.prototype.hasOwnProperty.call(obj, key);\n}\n\nexport function safeGet(\n obj: T,\n key: K\n): T[K] | undefined {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n return obj[key];\n } else {\n return undefined;\n }\n}\n\nexport function isEmpty(obj: object): obj is {} {\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n return false;\n }\n }\n return true;\n}\n\nexport function map(\n obj: { [key in K]: V },\n fn: (value: V, key: K, obj: { [key in K]: V }) => U,\n contextObj?: unknown\n): { [key in K]: U } {\n const res: Partial<{ [key in K]: U }> = {};\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n res[key] = fn.call(contextObj, obj[key], key, obj);\n }\n }\n return res as { [key in K]: U };\n}\n\n/**\n * Deep equal two objects. Support Arrays and Objects.\n */\nexport function deepEqual(a: object, b: object): boolean {\n if (a === b) {\n return true;\n }\n\n const aKeys = Object.keys(a);\n const bKeys = Object.keys(b);\n for (const k of aKeys) {\n if (!bKeys.includes(k)) {\n return false;\n }\n\n const aProp = (a as Record)[k];\n const bProp = (b as Record)[k];\n if (isObject(aProp) && isObject(bProp)) {\n if (!deepEqual(aProp, bProp)) {\n return false;\n }\n } else if (aProp !== bProp) {\n return false;\n }\n }\n\n for (const k of bKeys) {\n if (!aKeys.includes(k)) {\n return false;\n }\n }\n return true;\n}\n\nfunction isObject(thing: unknown): thing is object {\n return thing !== null && typeof thing === 'object';\n}\n", "/**\n * @license\n * Copyright 2022 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Deferred } from './deferred';\n\n/**\n * Rejects if the given promise doesn't resolve in timeInMS milliseconds.\n * @internal\n */\nexport function promiseWithTimeout(\n promise: Promise,\n timeInMS = 2000\n): Promise {\n const deferredPromise = new Deferred();\n setTimeout(() => deferredPromise.reject('timeout!'), timeInMS);\n promise.then(deferredPromise.resolve, deferredPromise.reject);\n return deferredPromise.promise;\n}\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Returns a querystring-formatted string (e.g. &arg=val&arg2=val2) from a\n * params object (e.g. {arg: 'val', arg2: 'val2'})\n * Note: You must prepend it with ? when adding it to a URL.\n */\nexport function querystring(querystringParams: {\n [key: string]: string | number;\n}): string {\n const params = [];\n for (const [key, value] of Object.entries(querystringParams)) {\n if (Array.isArray(value)) {\n value.forEach(arrayVal => {\n params.push(\n encodeURIComponent(key) + '=' + encodeURIComponent(arrayVal)\n );\n });\n } else {\n params.push(encodeURIComponent(key) + '=' + encodeURIComponent(value));\n }\n }\n return params.length ? '&' + params.join('&') : '';\n}\n\n/**\n * Decodes a querystring (e.g. ?arg=val&arg2=val2) into a params object\n * (e.g. {arg: 'val', arg2: 'val2'})\n */\nexport function querystringDecode(querystring: string): Record {\n const obj: Record = {};\n const tokens = querystring.replace(/^\\?/, '').split('&');\n\n tokens.forEach(token => {\n if (token) {\n const [key, value] = token.split('=');\n obj[decodeURIComponent(key)] = decodeURIComponent(value);\n }\n });\n return obj;\n}\n\n/**\n * Extract the query string part of a URL, including the leading question mark (if present).\n */\nexport function extractQuerystring(url: string): string {\n const queryStart = url.indexOf('?');\n if (!queryStart) {\n return '';\n }\n const fragmentStart = url.indexOf('#', queryStart);\n return url.substring(\n queryStart,\n fragmentStart > 0 ? fragmentStart : undefined\n );\n}\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * @fileoverview SHA-1 cryptographic hash.\n * Variable names follow the notation in FIPS PUB 180-3:\n * http://csrc.nist.gov/publications/fips/fips180-3/fips180-3_final.pdf.\n *\n * Usage:\n * var sha1 = new sha1();\n * sha1.update(bytes);\n * var hash = sha1.digest();\n *\n * Performance:\n * Chrome 23: ~400 Mbit/s\n * Firefox 16: ~250 Mbit/s\n *\n */\n\n/**\n * SHA-1 cryptographic hash constructor.\n *\n * The properties declared here are discussed in the above algorithm document.\n * @constructor\n * @final\n * @struct\n */\nexport class Sha1 {\n /**\n * Holds the previous values of accumulated variables a-e in the compress_\n * function.\n * @private\n */\n private chain_: number[] = [];\n\n /**\n * A buffer holding the partially computed hash result.\n * @private\n */\n private buf_: number[] = [];\n\n /**\n * An array of 80 bytes, each a part of the message to be hashed. Referred to\n * as the message schedule in the docs.\n * @private\n */\n private W_: number[] = [];\n\n /**\n * Contains data needed to pad messages less than 64 bytes.\n * @private\n */\n private pad_: number[] = [];\n\n /**\n * @private {number}\n */\n private inbuf_: number = 0;\n\n /**\n * @private {number}\n */\n private total_: number = 0;\n\n blockSize: number;\n\n constructor() {\n this.blockSize = 512 / 8;\n\n this.pad_[0] = 128;\n for (let i = 1; i < this.blockSize; ++i) {\n this.pad_[i] = 0;\n }\n\n this.reset();\n }\n\n reset(): void {\n this.chain_[0] = 0x67452301;\n this.chain_[1] = 0xefcdab89;\n this.chain_[2] = 0x98badcfe;\n this.chain_[3] = 0x10325476;\n this.chain_[4] = 0xc3d2e1f0;\n\n this.inbuf_ = 0;\n this.total_ = 0;\n }\n\n /**\n * Internal compress helper function.\n * @param buf Block to compress.\n * @param offset Offset of the block in the buffer.\n * @private\n */\n compress_(buf: number[] | Uint8Array | string, offset?: number): void {\n if (!offset) {\n offset = 0;\n }\n\n const W = this.W_;\n\n // get 16 big endian words\n if (typeof buf === 'string') {\n for (let i = 0; i < 16; i++) {\n // TODO(user): [bug 8140122] Recent versions of Safari for Mac OS and iOS\n // have a bug that turns the post-increment ++ operator into pre-increment\n // during JIT compilation. We have code that depends heavily on SHA-1 for\n // correctness and which is affected by this bug, so I've removed all uses\n // of post-increment ++ in which the result value is used. We can revert\n // this change once the Safari bug\n // (https://bugs.webkit.org/show_bug.cgi?id=109036) has been fixed and\n // most clients have been updated.\n W[i] =\n (buf.charCodeAt(offset) << 24) |\n (buf.charCodeAt(offset + 1) << 16) |\n (buf.charCodeAt(offset + 2) << 8) |\n buf.charCodeAt(offset + 3);\n offset += 4;\n }\n } else {\n for (let i = 0; i < 16; i++) {\n W[i] =\n (buf[offset] << 24) |\n (buf[offset + 1] << 16) |\n (buf[offset + 2] << 8) |\n buf[offset + 3];\n offset += 4;\n }\n }\n\n // expand to 80 words\n for (let i = 16; i < 80; i++) {\n const t = W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16];\n W[i] = ((t << 1) | (t >>> 31)) & 0xffffffff;\n }\n\n let a = this.chain_[0];\n let b = this.chain_[1];\n let c = this.chain_[2];\n let d = this.chain_[3];\n let e = this.chain_[4];\n let f, k;\n\n // TODO(user): Try to unroll this loop to speed up the computation.\n for (let i = 0; i < 80; i++) {\n if (i < 40) {\n if (i < 20) {\n f = d ^ (b & (c ^ d));\n k = 0x5a827999;\n } else {\n f = b ^ c ^ d;\n k = 0x6ed9eba1;\n }\n } else {\n if (i < 60) {\n f = (b & c) | (d & (b | c));\n k = 0x8f1bbcdc;\n } else {\n f = b ^ c ^ d;\n k = 0xca62c1d6;\n }\n }\n\n const t = (((a << 5) | (a >>> 27)) + f + e + k + W[i]) & 0xffffffff;\n e = d;\n d = c;\n c = ((b << 30) | (b >>> 2)) & 0xffffffff;\n b = a;\n a = t;\n }\n\n this.chain_[0] = (this.chain_[0] + a) & 0xffffffff;\n this.chain_[1] = (this.chain_[1] + b) & 0xffffffff;\n this.chain_[2] = (this.chain_[2] + c) & 0xffffffff;\n this.chain_[3] = (this.chain_[3] + d) & 0xffffffff;\n this.chain_[4] = (this.chain_[4] + e) & 0xffffffff;\n }\n\n update(bytes?: number[] | Uint8Array | string, length?: number): void {\n // TODO(johnlenz): tighten the function signature and remove this check\n if (bytes == null) {\n return;\n }\n\n if (length === undefined) {\n length = bytes.length;\n }\n\n const lengthMinusBlock = length - this.blockSize;\n let n = 0;\n // Using local instead of member variables gives ~5% speedup on Firefox 16.\n const buf = this.buf_;\n let inbuf = this.inbuf_;\n\n // The outer while loop should execute at most twice.\n while (n < length) {\n // When we have no data in the block to top up, we can directly process the\n // input buffer (assuming it contains sufficient data). This gives ~25%\n // speedup on Chrome 23 and ~15% speedup on Firefox 16, but requires that\n // the data is provided in large chunks (or in multiples of 64 bytes).\n if (inbuf === 0) {\n while (n <= lengthMinusBlock) {\n this.compress_(bytes, n);\n n += this.blockSize;\n }\n }\n\n if (typeof bytes === 'string') {\n while (n < length) {\n buf[inbuf] = bytes.charCodeAt(n);\n ++inbuf;\n ++n;\n if (inbuf === this.blockSize) {\n this.compress_(buf);\n inbuf = 0;\n // Jump to the outer loop so we use the full-block optimization.\n break;\n }\n }\n } else {\n while (n < length) {\n buf[inbuf] = bytes[n];\n ++inbuf;\n ++n;\n if (inbuf === this.blockSize) {\n this.compress_(buf);\n inbuf = 0;\n // Jump to the outer loop so we use the full-block optimization.\n break;\n }\n }\n }\n }\n\n this.inbuf_ = inbuf;\n this.total_ += length;\n }\n\n /** @override */\n digest(): number[] {\n const digest: number[] = [];\n let totalBits = this.total_ * 8;\n\n // Add pad 0x80 0x00*.\n if (this.inbuf_ < 56) {\n this.update(this.pad_, 56 - this.inbuf_);\n } else {\n this.update(this.pad_, this.blockSize - (this.inbuf_ - 56));\n }\n\n // Add # bits.\n for (let i = this.blockSize - 1; i >= 56; i--) {\n this.buf_[i] = totalBits & 255;\n totalBits /= 256; // Don't use bit-shifting here!\n }\n\n this.compress_(this.buf_);\n\n let n = 0;\n for (let i = 0; i < 5; i++) {\n for (let j = 24; j >= 0; j -= 8) {\n digest[n] = (this.chain_[i] >> j) & 255;\n ++n;\n }\n }\n return digest;\n }\n}\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nexport type NextFn = (value: T) => void;\nexport type ErrorFn = (error: Error) => void;\nexport type CompleteFn = () => void;\n\nexport interface Observer {\n // Called once for each value in a stream of values.\n next: NextFn;\n\n // A stream terminates by a single call to EITHER error() or complete().\n error: ErrorFn;\n\n // No events will be sent to next() once complete() is called.\n complete: CompleteFn;\n}\n\nexport type PartialObserver = Partial>;\n\n// TODO: Support also Unsubscribe.unsubscribe?\nexport type Unsubscribe = () => void;\n\n/**\n * The Subscribe interface has two forms - passing the inline function\n * callbacks, or a object interface with callback properties.\n */\nexport interface Subscribe {\n (next?: NextFn, error?: ErrorFn, complete?: CompleteFn): Unsubscribe;\n (observer: PartialObserver): Unsubscribe;\n}\n\nexport interface Observable {\n // Subscribe method\n subscribe: Subscribe;\n}\n\nexport type Executor = (observer: Observer) => void;\n\n/**\n * Helper to make a Subscribe function (just like Promise helps make a\n * Thenable).\n *\n * @param executor Function which can make calls to a single Observer\n * as a proxy.\n * @param onNoObservers Callback when count of Observers goes to zero.\n */\nexport function createSubscribe(\n executor: Executor,\n onNoObservers?: Executor\n): Subscribe {\n const proxy = new ObserverProxy(executor, onNoObservers);\n return proxy.subscribe.bind(proxy);\n}\n\n/**\n * Implement fan-out for any number of Observers attached via a subscribe\n * function.\n */\nclass ObserverProxy implements Observer {\n private observers: Array> | undefined = [];\n private unsubscribes: Unsubscribe[] = [];\n private onNoObservers: Executor | undefined;\n private observerCount = 0;\n // Micro-task scheduling by calling task.then().\n private task = Promise.resolve();\n private finalized = false;\n private finalError?: Error;\n\n /**\n * @param executor Function which can make calls to a single Observer\n * as a proxy.\n * @param onNoObservers Callback when count of Observers goes to zero.\n */\n constructor(executor: Executor, onNoObservers?: Executor) {\n this.onNoObservers = onNoObservers;\n // Call the executor asynchronously so subscribers that are called\n // synchronously after the creation of the subscribe function\n // can still receive the very first value generated in the executor.\n this.task\n .then(() => {\n executor(this);\n })\n .catch(e => {\n this.error(e);\n });\n }\n\n next(value: T): void {\n this.forEachObserver((observer: Observer) => {\n observer.next(value);\n });\n }\n\n error(error: Error): void {\n this.forEachObserver((observer: Observer) => {\n observer.error(error);\n });\n this.close(error);\n }\n\n complete(): void {\n this.forEachObserver((observer: Observer) => {\n observer.complete();\n });\n this.close();\n }\n\n /**\n * Subscribe function that can be used to add an Observer to the fan-out list.\n *\n * - We require that no event is sent to a subscriber sychronously to their\n * call to subscribe().\n */\n subscribe(\n nextOrObserver?: NextFn | PartialObserver,\n error?: ErrorFn,\n complete?: CompleteFn\n ): Unsubscribe {\n let observer: Observer;\n\n if (\n nextOrObserver === undefined &&\n error === undefined &&\n complete === undefined\n ) {\n throw new Error('Missing Observer.');\n }\n\n // Assemble an Observer object when passed as callback functions.\n if (\n implementsAnyMethods(nextOrObserver as { [key: string]: unknown }, [\n 'next',\n 'error',\n 'complete'\n ])\n ) {\n observer = nextOrObserver as Observer;\n } else {\n observer = {\n next: nextOrObserver as NextFn,\n error,\n complete\n } as Observer;\n }\n\n if (observer.next === undefined) {\n observer.next = noop as NextFn;\n }\n if (observer.error === undefined) {\n observer.error = noop as ErrorFn;\n }\n if (observer.complete === undefined) {\n observer.complete = noop as CompleteFn;\n }\n\n const unsub = this.unsubscribeOne.bind(this, this.observers!.length);\n\n // Attempt to subscribe to a terminated Observable - we\n // just respond to the Observer with the final error or complete\n // event.\n if (this.finalized) {\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.task.then(() => {\n try {\n if (this.finalError) {\n observer.error(this.finalError);\n } else {\n observer.complete();\n }\n } catch (e) {\n // nothing\n }\n return;\n });\n }\n\n this.observers!.push(observer as Observer);\n\n return unsub;\n }\n\n // Unsubscribe is synchronous - we guarantee that no events are sent to\n // any unsubscribed Observer.\n private unsubscribeOne(i: number): void {\n if (this.observers === undefined || this.observers[i] === undefined) {\n return;\n }\n\n delete this.observers[i];\n\n this.observerCount -= 1;\n if (this.observerCount === 0 && this.onNoObservers !== undefined) {\n this.onNoObservers(this);\n }\n }\n\n private forEachObserver(fn: (observer: Observer) => void): void {\n if (this.finalized) {\n // Already closed by previous event....just eat the additional values.\n return;\n }\n\n // Since sendOne calls asynchronously - there is no chance that\n // this.observers will become undefined.\n for (let i = 0; i < this.observers!.length; i++) {\n this.sendOne(i, fn);\n }\n }\n\n // Call the Observer via one of it's callback function. We are careful to\n // confirm that the observe has not been unsubscribed since this asynchronous\n // function had been queued.\n private sendOne(i: number, fn: (observer: Observer) => void): void {\n // Execute the callback asynchronously\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.task.then(() => {\n if (this.observers !== undefined && this.observers[i] !== undefined) {\n try {\n fn(this.observers[i]);\n } catch (e) {\n // Ignore exceptions raised in Observers or missing methods of an\n // Observer.\n // Log error to console. b/31404806\n if (typeof console !== 'undefined' && console.error) {\n console.error(e);\n }\n }\n }\n });\n }\n\n private close(err?: Error): void {\n if (this.finalized) {\n return;\n }\n this.finalized = true;\n if (err !== undefined) {\n this.finalError = err;\n }\n // Proxy is no longer needed - garbage collect references\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.task.then(() => {\n this.observers = undefined;\n this.onNoObservers = undefined;\n });\n }\n}\n\n/** Turn synchronous function into one called asynchronously. */\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport function async(fn: Function, onError?: ErrorFn): Function {\n return (...args: unknown[]) => {\n Promise.resolve(true)\n .then(() => {\n fn(...args);\n })\n .catch((error: Error) => {\n if (onError) {\n onError(error);\n }\n });\n };\n}\n\n/**\n * Return true if the object passed in implements any of the named methods.\n */\nfunction implementsAnyMethods(\n obj: { [key: string]: unknown },\n methods: string[]\n): boolean {\n if (typeof obj !== 'object' || obj === null) {\n return false;\n }\n\n for (const method of methods) {\n if (method in obj && typeof obj[method] === 'function') {\n return true;\n }\n }\n\n return false;\n}\n\nfunction noop(): void {\n // do nothing\n}\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Check to make sure the appropriate number of arguments are provided for a public function.\n * Throws an error if it fails.\n *\n * @param fnName The function name\n * @param minCount The minimum number of arguments to allow for the function call\n * @param maxCount The maximum number of argument to allow for the function call\n * @param argCount The actual number of arguments provided.\n */\nexport const validateArgCount = function (\n fnName: string,\n minCount: number,\n maxCount: number,\n argCount: number\n): void {\n let argError;\n if (argCount < minCount) {\n argError = 'at least ' + minCount;\n } else if (argCount > maxCount) {\n argError = maxCount === 0 ? 'none' : 'no more than ' + maxCount;\n }\n if (argError) {\n const error =\n fnName +\n ' failed: Was called with ' +\n argCount +\n (argCount === 1 ? ' argument.' : ' arguments.') +\n ' Expects ' +\n argError +\n '.';\n throw new Error(error);\n }\n};\n\n/**\n * Generates a string to prefix an error message about failed argument validation\n *\n * @param fnName The function name\n * @param argName The name of the argument\n * @return The prefix to add to the error thrown for validation.\n */\nexport function errorPrefix(fnName: string, argName: string): string {\n return `${fnName} failed: ${argName} argument `;\n}\n\n/**\n * @param fnName\n * @param argumentNumber\n * @param namespace\n * @param optional\n */\nexport function validateNamespace(\n fnName: string,\n namespace: string,\n optional: boolean\n): void {\n if (optional && !namespace) {\n return;\n }\n if (typeof namespace !== 'string') {\n //TODO: I should do more validation here. We only allow certain chars in namespaces.\n throw new Error(\n errorPrefix(fnName, 'namespace') + 'must be a valid firebase namespace.'\n );\n }\n}\n\nexport function validateCallback(\n fnName: string,\n argumentName: string,\n // eslint-disable-next-line @typescript-eslint/ban-types\n callback: Function,\n optional: boolean\n): void {\n if (optional && !callback) {\n return;\n }\n if (typeof callback !== 'function') {\n throw new Error(\n errorPrefix(fnName, argumentName) + 'must be a valid function.'\n );\n }\n}\n\nexport function validateContextObject(\n fnName: string,\n argumentName: string,\n context: unknown,\n optional: boolean\n): void {\n if (optional && !context) {\n return;\n }\n if (typeof context !== 'object' || context === null) {\n throw new Error(\n errorPrefix(fnName, argumentName) + 'must be a valid context object.'\n );\n }\n}\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { assert } from './assert';\n\n// Code originally came from goog.crypt.stringToUtf8ByteArray, but for some reason they\n// automatically replaced '\\r\\n' with '\\n', and they didn't handle surrogate pairs,\n// so it's been modified.\n\n// Note that not all Unicode characters appear as single characters in JavaScript strings.\n// fromCharCode returns the UTF-16 encoding of a character - so some Unicode characters\n// use 2 characters in Javascript. All 4-byte UTF-8 characters begin with a first\n// character in the range 0xD800 - 0xDBFF (the first character of a so-called surrogate\n// pair).\n// See http://www.ecma-international.org/ecma-262/5.1/#sec-15.1.3\n\n/**\n * @param {string} str\n * @return {Array}\n */\nexport const stringToByteArray = function (str: string): number[] {\n const out: number[] = [];\n let p = 0;\n for (let i = 0; i < str.length; i++) {\n let c = str.charCodeAt(i);\n\n // Is this the lead surrogate in a surrogate pair?\n if (c >= 0xd800 && c <= 0xdbff) {\n const high = c - 0xd800; // the high 10 bits.\n i++;\n assert(i < str.length, 'Surrogate pair missing trail surrogate.');\n const low = str.charCodeAt(i) - 0xdc00; // the low 10 bits.\n c = 0x10000 + (high << 10) + low;\n }\n\n if (c < 128) {\n out[p++] = c;\n } else if (c < 2048) {\n out[p++] = (c >> 6) | 192;\n out[p++] = (c & 63) | 128;\n } else if (c < 65536) {\n out[p++] = (c >> 12) | 224;\n out[p++] = ((c >> 6) & 63) | 128;\n out[p++] = (c & 63) | 128;\n } else {\n out[p++] = (c >> 18) | 240;\n out[p++] = ((c >> 12) & 63) | 128;\n out[p++] = ((c >> 6) & 63) | 128;\n out[p++] = (c & 63) | 128;\n }\n }\n return out;\n};\n\n/**\n * Calculate length without actually converting; useful for doing cheaper validation.\n * @param {string} str\n * @return {number}\n */\nexport const stringLength = function (str: string): number {\n let p = 0;\n for (let i = 0; i < str.length; i++) {\n const c = str.charCodeAt(i);\n if (c < 128) {\n p++;\n } else if (c < 2048) {\n p += 2;\n } else if (c >= 0xd800 && c <= 0xdbff) {\n // Lead surrogate of a surrogate pair. The pair together will take 4 bytes to represent.\n p += 4;\n i++; // skip trail surrogate.\n } else {\n p += 3;\n }\n }\n return p;\n};\n", "/**\n * @license\n * Copyright 2022 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Copied from https://stackoverflow.com/a/2117523\n * Generates a new uuid.\n * @public\n */\nexport const uuidv4 = function (): string {\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {\n const r = (Math.random() * 16) | 0,\n v = c === 'x' ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n};\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * The amount of milliseconds to exponentially increase.\n */\nconst DEFAULT_INTERVAL_MILLIS = 1000;\n\n/**\n * The factor to backoff by.\n * Should be a number greater than 1.\n */\nconst DEFAULT_BACKOFF_FACTOR = 2;\n\n/**\n * The maximum milliseconds to increase to.\n *\n *

Visible for testing\n */\nexport const MAX_VALUE_MILLIS = 4 * 60 * 60 * 1000; // Four hours, like iOS and Android.\n\n/**\n * The percentage of backoff time to randomize by.\n * See\n * http://go/safe-client-behavior#step-1-determine-the-appropriate-retry-interval-to-handle-spike-traffic\n * for context.\n *\n *

Visible for testing\n */\nexport const RANDOM_FACTOR = 0.5;\n\n/**\n * Based on the backoff method from\n * https://github.com/google/closure-library/blob/master/closure/goog/math/exponentialbackoff.js.\n * Extracted here so we don't need to pass metadata and a stateful ExponentialBackoff object around.\n */\nexport function calculateBackoffMillis(\n backoffCount: number,\n intervalMillis: number = DEFAULT_INTERVAL_MILLIS,\n backoffFactor: number = DEFAULT_BACKOFF_FACTOR\n): number {\n // Calculates an exponentially increasing value.\n // Deviation: calculates value from count and a constant interval, so we only need to save value\n // and count to restore state.\n const currBaseValue = intervalMillis * Math.pow(backoffFactor, backoffCount);\n\n // A random \"fuzz\" to avoid waves of retries.\n // Deviation: randomFactor is required.\n const randomWait = Math.round(\n // A fraction of the backoff value to add/subtract.\n // Deviation: changes multiplication order to improve readability.\n RANDOM_FACTOR *\n currBaseValue *\n // A random float (rounded to int by Math.round above) in the range [-1, 1]. Determines\n // if we add or subtract.\n (Math.random() - 0.5) *\n 2\n );\n\n // Limits backoff to max to avoid effectively permanent backoff.\n return Math.min(MAX_VALUE_MILLIS, currBaseValue + randomWait);\n}\n", "/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Provide English ordinal letters after a number\n */\nexport function ordinal(i: number): string {\n if (!Number.isFinite(i)) {\n return `${i}`;\n }\n return i + indicator(i);\n}\n\nfunction indicator(i: number): string {\n i = Math.abs(i);\n const cent = i % 100;\n if (cent >= 10 && cent <= 20) {\n return 'th';\n }\n const dec = i % 10;\n if (dec === 1) {\n return 'st';\n }\n if (dec === 2) {\n return 'nd';\n }\n if (dec === 3) {\n return 'rd';\n }\n return 'th';\n}\n", "/**\n * @license\n * Copyright 2021 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport interface Compat {\n _delegate: T;\n}\n\nexport function getModularInstance(\n service: Compat | ExpService\n): ExpService {\n if (service && (service as Compat)._delegate) {\n return (service as Compat)._delegate;\n } else {\n return service as ExpService;\n }\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n InstantiationMode,\n InstanceFactory,\n ComponentType,\n Dictionary,\n Name,\n onInstanceCreatedCallback\n} from './types';\n\n/**\n * Component for service name T, e.g. `auth`, `auth-internal`\n */\nexport class Component {\n multipleInstances = false;\n /**\n * Properties to be added to the service namespace\n */\n serviceProps: Dictionary = {};\n\n instantiationMode = InstantiationMode.LAZY;\n\n onInstanceCreated: onInstanceCreatedCallback | null = null;\n\n /**\n *\n * @param name The public service name, e.g. app, auth, firestore, database\n * @param instanceFactory Service factory responsible for creating the public interface\n * @param type whether the service provided by the component is public or private\n */\n constructor(\n readonly name: T,\n readonly instanceFactory: InstanceFactory,\n readonly type: ComponentType\n ) {}\n\n setInstantiationMode(mode: InstantiationMode): this {\n this.instantiationMode = mode;\n return this;\n }\n\n setMultipleInstances(multipleInstances: boolean): this {\n this.multipleInstances = multipleInstances;\n return this;\n }\n\n setServiceProps(props: Dictionary): this {\n this.serviceProps = props;\n return this;\n }\n\n setInstanceCreatedCallback(callback: onInstanceCreatedCallback): this {\n this.onInstanceCreated = callback;\n return this;\n }\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport const DEFAULT_ENTRY_NAME = '[DEFAULT]';\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Deferred } from '@firebase/util';\nimport { ComponentContainer } from './component_container';\nimport { DEFAULT_ENTRY_NAME } from './constants';\nimport {\n InitializeOptions,\n InstantiationMode,\n Name,\n NameServiceMapping,\n OnInitCallBack\n} from './types';\nimport { Component } from './component';\n\n/**\n * Provider for instance for service name T, e.g. 'auth', 'auth-internal'\n * NameServiceMapping[T] is an alias for the type of the instance\n */\nexport class Provider {\n private component: Component | null = null;\n private readonly instances: Map = new Map();\n private readonly instancesDeferred: Map<\n string,\n Deferred\n > = new Map();\n private readonly instancesOptions: Map> =\n new Map();\n private onInitCallbacks: Map>> = new Map();\n\n constructor(\n private readonly name: T,\n private readonly container: ComponentContainer\n ) {}\n\n /**\n * @param identifier A provider can provide mulitple instances of a service\n * if this.component.multipleInstances is true.\n */\n get(identifier?: string): Promise {\n // if multipleInstances is not supported, use the default name\n const normalizedIdentifier = this.normalizeInstanceIdentifier(identifier);\n\n if (!this.instancesDeferred.has(normalizedIdentifier)) {\n const deferred = new Deferred();\n this.instancesDeferred.set(normalizedIdentifier, deferred);\n\n if (\n this.isInitialized(normalizedIdentifier) ||\n this.shouldAutoInitialize()\n ) {\n // initialize the service if it can be auto-initialized\n try {\n const instance = this.getOrInitializeService({\n instanceIdentifier: normalizedIdentifier\n });\n if (instance) {\n deferred.resolve(instance);\n }\n } catch (e) {\n // when the instance factory throws an exception during get(), it should not cause\n // a fatal error. We just return the unresolved promise in this case.\n }\n }\n }\n\n return this.instancesDeferred.get(normalizedIdentifier)!.promise;\n }\n\n /**\n *\n * @param options.identifier A provider can provide mulitple instances of a service\n * if this.component.multipleInstances is true.\n * @param options.optional If optional is false or not provided, the method throws an error when\n * the service is not immediately available.\n * If optional is true, the method returns null if the service is not immediately available.\n */\n getImmediate(options: {\n identifier?: string;\n optional: true;\n }): NameServiceMapping[T] | null;\n getImmediate(options?: {\n identifier?: string;\n optional?: false;\n }): NameServiceMapping[T];\n getImmediate(options?: {\n identifier?: string;\n optional?: boolean;\n }): NameServiceMapping[T] | null {\n // if multipleInstances is not supported, use the default name\n const normalizedIdentifier = this.normalizeInstanceIdentifier(\n options?.identifier\n );\n const optional = options?.optional ?? false;\n\n if (\n this.isInitialized(normalizedIdentifier) ||\n this.shouldAutoInitialize()\n ) {\n try {\n return this.getOrInitializeService({\n instanceIdentifier: normalizedIdentifier\n });\n } catch (e) {\n if (optional) {\n return null;\n } else {\n throw e;\n }\n }\n } else {\n // In case a component is not initialized and should/can not be auto-initialized at the moment, return null if the optional flag is set, or throw\n if (optional) {\n return null;\n } else {\n throw Error(`Service ${this.name} is not available`);\n }\n }\n }\n\n getComponent(): Component | null {\n return this.component;\n }\n\n setComponent(component: Component): void {\n if (component.name !== this.name) {\n throw Error(\n `Mismatching Component ${component.name} for Provider ${this.name}.`\n );\n }\n\n if (this.component) {\n throw Error(`Component for ${this.name} has already been provided`);\n }\n\n this.component = component;\n\n // return early without attempting to initialize the component if the component requires explicit initialization (calling `Provider.initialize()`)\n if (!this.shouldAutoInitialize()) {\n return;\n }\n\n // if the service is eager, initialize the default instance\n if (isComponentEager(component)) {\n try {\n this.getOrInitializeService({ instanceIdentifier: DEFAULT_ENTRY_NAME });\n } catch (e) {\n // when the instance factory for an eager Component throws an exception during the eager\n // initialization, it should not cause a fatal error.\n // TODO: Investigate if we need to make it configurable, because some component may want to cause\n // a fatal error in this case?\n }\n }\n\n // Create service instances for the pending promises and resolve them\n // NOTE: if this.multipleInstances is false, only the default instance will be created\n // and all promises with resolve with it regardless of the identifier.\n for (const [\n instanceIdentifier,\n instanceDeferred\n ] of this.instancesDeferred.entries()) {\n const normalizedIdentifier =\n this.normalizeInstanceIdentifier(instanceIdentifier);\n\n try {\n // `getOrInitializeService()` should always return a valid instance since a component is guaranteed. use ! to make typescript happy.\n const instance = this.getOrInitializeService({\n instanceIdentifier: normalizedIdentifier\n })!;\n instanceDeferred.resolve(instance);\n } catch (e) {\n // when the instance factory throws an exception, it should not cause\n // a fatal error. We just leave the promise unresolved.\n }\n }\n }\n\n clearInstance(identifier: string = DEFAULT_ENTRY_NAME): void {\n this.instancesDeferred.delete(identifier);\n this.instancesOptions.delete(identifier);\n this.instances.delete(identifier);\n }\n\n // app.delete() will call this method on every provider to delete the services\n // TODO: should we mark the provider as deleted?\n async delete(): Promise {\n const services = Array.from(this.instances.values());\n\n await Promise.all([\n ...services\n .filter(service => 'INTERNAL' in service) // legacy services\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n .map(service => (service as any).INTERNAL!.delete()),\n ...services\n .filter(service => '_delete' in service) // modularized services\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n .map(service => (service as any)._delete())\n ]);\n }\n\n isComponentSet(): boolean {\n return this.component != null;\n }\n\n isInitialized(identifier: string = DEFAULT_ENTRY_NAME): boolean {\n return this.instances.has(identifier);\n }\n\n getOptions(identifier: string = DEFAULT_ENTRY_NAME): Record {\n return this.instancesOptions.get(identifier) || {};\n }\n\n initialize(opts: InitializeOptions = {}): NameServiceMapping[T] {\n const { options = {} } = opts;\n const normalizedIdentifier = this.normalizeInstanceIdentifier(\n opts.instanceIdentifier\n );\n if (this.isInitialized(normalizedIdentifier)) {\n throw Error(\n `${this.name}(${normalizedIdentifier}) has already been initialized`\n );\n }\n\n if (!this.isComponentSet()) {\n throw Error(`Component ${this.name} has not been registered yet`);\n }\n\n const instance = this.getOrInitializeService({\n instanceIdentifier: normalizedIdentifier,\n options\n })!;\n\n // resolve any pending promise waiting for the service instance\n for (const [\n instanceIdentifier,\n instanceDeferred\n ] of this.instancesDeferred.entries()) {\n const normalizedDeferredIdentifier =\n this.normalizeInstanceIdentifier(instanceIdentifier);\n if (normalizedIdentifier === normalizedDeferredIdentifier) {\n instanceDeferred.resolve(instance);\n }\n }\n\n return instance;\n }\n\n /**\n *\n * @param callback - a function that will be invoked after the provider has been initialized by calling provider.initialize().\n * The function is invoked SYNCHRONOUSLY, so it should not execute any longrunning tasks in order to not block the program.\n *\n * @param identifier An optional instance identifier\n * @returns a function to unregister the callback\n */\n onInit(callback: OnInitCallBack, identifier?: string): () => void {\n const normalizedIdentifier = this.normalizeInstanceIdentifier(identifier);\n const existingCallbacks =\n this.onInitCallbacks.get(normalizedIdentifier) ??\n new Set>();\n existingCallbacks.add(callback);\n this.onInitCallbacks.set(normalizedIdentifier, existingCallbacks);\n\n const existingInstance = this.instances.get(normalizedIdentifier);\n if (existingInstance) {\n callback(existingInstance, normalizedIdentifier);\n }\n\n return () => {\n existingCallbacks.delete(callback);\n };\n }\n\n /**\n * Invoke onInit callbacks synchronously\n * @param instance the service instance`\n */\n private invokeOnInitCallbacks(\n instance: NameServiceMapping[T],\n identifier: string\n ): void {\n const callbacks = this.onInitCallbacks.get(identifier);\n if (!callbacks) {\n return;\n }\n for (const callback of callbacks) {\n try {\n callback(instance, identifier);\n } catch {\n // ignore errors in the onInit callback\n }\n }\n }\n\n private getOrInitializeService({\n instanceIdentifier,\n options = {}\n }: {\n instanceIdentifier: string;\n options?: Record;\n }): NameServiceMapping[T] | null {\n let instance = this.instances.get(instanceIdentifier);\n if (!instance && this.component) {\n instance = this.component.instanceFactory(this.container, {\n instanceIdentifier: normalizeIdentifierForFactory(instanceIdentifier),\n options\n });\n this.instances.set(instanceIdentifier, instance);\n this.instancesOptions.set(instanceIdentifier, options);\n\n /**\n * Invoke onInit listeners.\n * Note this.component.onInstanceCreated is different, which is used by the component creator,\n * while onInit listeners are registered by consumers of the provider.\n */\n this.invokeOnInitCallbacks(instance, instanceIdentifier);\n\n /**\n * Order is important\n * onInstanceCreated() should be called after this.instances.set(instanceIdentifier, instance); which\n * makes `isInitialized()` return true.\n */\n if (this.component.onInstanceCreated) {\n try {\n this.component.onInstanceCreated(\n this.container,\n instanceIdentifier,\n instance\n );\n } catch {\n // ignore errors in the onInstanceCreatedCallback\n }\n }\n }\n\n return instance || null;\n }\n\n private normalizeInstanceIdentifier(\n identifier: string = DEFAULT_ENTRY_NAME\n ): string {\n if (this.component) {\n return this.component.multipleInstances ? identifier : DEFAULT_ENTRY_NAME;\n } else {\n return identifier; // assume multiple instances are supported before the component is provided.\n }\n }\n\n private shouldAutoInitialize(): boolean {\n return (\n !!this.component &&\n this.component.instantiationMode !== InstantiationMode.EXPLICIT\n );\n }\n}\n\n// undefined should be passed to the service factory for the default instance\nfunction normalizeIdentifierForFactory(identifier: string): string | undefined {\n return identifier === DEFAULT_ENTRY_NAME ? undefined : identifier;\n}\n\nfunction isComponentEager(component: Component): boolean {\n return component.instantiationMode === InstantiationMode.EAGER;\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Provider } from './provider';\nimport { Component } from './component';\nimport { Name } from './types';\n\n/**\n * ComponentContainer that provides Providers for service name T, e.g. `auth`, `auth-internal`\n */\nexport class ComponentContainer {\n private readonly providers = new Map>();\n\n constructor(private readonly name: string) {}\n\n /**\n *\n * @param component Component being added\n * @param overwrite When a component with the same name has already been registered,\n * if overwrite is true: overwrite the existing component with the new component and create a new\n * provider with the new component. It can be useful in tests where you want to use different mocks\n * for different tests.\n * if overwrite is false: throw an exception\n */\n addComponent(component: Component): void {\n const provider = this.getProvider(component.name);\n if (provider.isComponentSet()) {\n throw new Error(\n `Component ${component.name} has already been registered with ${this.name}`\n );\n }\n\n provider.setComponent(component);\n }\n\n addOrOverwriteComponent(component: Component): void {\n const provider = this.getProvider(component.name);\n if (provider.isComponentSet()) {\n // delete the existing provider from the container, so we can register the new component\n this.providers.delete(component.name);\n }\n\n this.addComponent(component);\n }\n\n /**\n * getProvider provides a type safe interface where it can only be called with a field name\n * present in NameServiceMapping interface.\n *\n * Firebase SDKs providing services should extend NameServiceMapping interface to register\n * themselves.\n */\n getProvider(name: T): Provider {\n if (this.providers.has(name)) {\n return this.providers.get(name) as unknown as Provider;\n }\n\n // create a Provider for a service that hasn't registered with Firebase\n const provider = new Provider(name, this);\n this.providers.set(name, provider as unknown as Provider);\n\n return provider as Provider;\n }\n\n getProviders(): Array> {\n return Array.from(this.providers.values());\n }\n}\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport type LogLevelString =\n | 'debug'\n | 'verbose'\n | 'info'\n | 'warn'\n | 'error'\n | 'silent';\n\nexport interface LogOptions {\n level: LogLevelString;\n}\n\nexport type LogCallback = (callbackParams: LogCallbackParams) => void;\n\nexport interface LogCallbackParams {\n level: LogLevelString;\n message: string;\n args: unknown[];\n type: string;\n}\n\n/**\n * A container for all of the Logger instances\n */\nexport const instances: Logger[] = [];\n\n/**\n * The JS SDK supports 5 log levels and also allows a user the ability to\n * silence the logs altogether.\n *\n * The order is a follows:\n * DEBUG < VERBOSE < INFO < WARN < ERROR\n *\n * All of the log types above the current log level will be captured (i.e. if\n * you set the log level to `INFO`, errors will still be logged, but `DEBUG` and\n * `VERBOSE` logs will not)\n */\nexport enum LogLevel {\n DEBUG,\n VERBOSE,\n INFO,\n WARN,\n ERROR,\n SILENT\n}\n\nconst levelStringToEnum: { [key in LogLevelString]: LogLevel } = {\n 'debug': LogLevel.DEBUG,\n 'verbose': LogLevel.VERBOSE,\n 'info': LogLevel.INFO,\n 'warn': LogLevel.WARN,\n 'error': LogLevel.ERROR,\n 'silent': LogLevel.SILENT\n};\n\n/**\n * The default log level\n */\nconst defaultLogLevel: LogLevel = LogLevel.INFO;\n\n/**\n * We allow users the ability to pass their own log handler. We will pass the\n * type of log, the current log level, and any other arguments passed (i.e. the\n * messages that the user wants to log) to this function.\n */\nexport type LogHandler = (\n loggerInstance: Logger,\n logType: LogLevel,\n ...args: unknown[]\n) => void;\n\n/**\n * By default, `console.debug` is not displayed in the developer console (in\n * chrome). To avoid forcing users to have to opt-in to these logs twice\n * (i.e. once for firebase, and once in the console), we are sending `DEBUG`\n * logs to the `console.log` function.\n */\nconst ConsoleMethod = {\n [LogLevel.DEBUG]: 'log',\n [LogLevel.VERBOSE]: 'log',\n [LogLevel.INFO]: 'info',\n [LogLevel.WARN]: 'warn',\n [LogLevel.ERROR]: 'error'\n};\n\n/**\n * The default log handler will forward DEBUG, VERBOSE, INFO, WARN, and ERROR\n * messages on to their corresponding console counterparts (if the log method\n * is supported by the current log level)\n */\nconst defaultLogHandler: LogHandler = (instance, logType, ...args): void => {\n if (logType < instance.logLevel) {\n return;\n }\n const now = new Date().toISOString();\n const method = ConsoleMethod[logType as keyof typeof ConsoleMethod];\n if (method) {\n console[method as 'log' | 'info' | 'warn' | 'error'](\n `[${now}] ${instance.name}:`,\n ...args\n );\n } else {\n throw new Error(\n `Attempted to log a message with an invalid logType (value: ${logType})`\n );\n }\n};\n\nexport class Logger {\n /**\n * Gives you an instance of a Logger to capture messages according to\n * Firebase's logging scheme.\n *\n * @param name The name that the logs will be associated with\n */\n constructor(public name: string) {\n /**\n * Capture the current instance for later use\n */\n instances.push(this);\n }\n\n /**\n * The log level of the given Logger instance.\n */\n private _logLevel = defaultLogLevel;\n\n get logLevel(): LogLevel {\n return this._logLevel;\n }\n\n set logLevel(val: LogLevel) {\n if (!(val in LogLevel)) {\n throw new TypeError(`Invalid value \"${val}\" assigned to \\`logLevel\\``);\n }\n this._logLevel = val;\n }\n\n // Workaround for setter/getter having to be the same type.\n setLogLevel(val: LogLevel | LogLevelString): void {\n this._logLevel = typeof val === 'string' ? levelStringToEnum[val] : val;\n }\n\n /**\n * The main (internal) log handler for the Logger instance.\n * Can be set to a new function in internal package code but not by user.\n */\n private _logHandler: LogHandler = defaultLogHandler;\n get logHandler(): LogHandler {\n return this._logHandler;\n }\n set logHandler(val: LogHandler) {\n if (typeof val !== 'function') {\n throw new TypeError('Value assigned to `logHandler` must be a function');\n }\n this._logHandler = val;\n }\n\n /**\n * The optional, additional, user-defined log handler for the Logger instance.\n */\n private _userLogHandler: LogHandler | null = null;\n get userLogHandler(): LogHandler | null {\n return this._userLogHandler;\n }\n set userLogHandler(val: LogHandler | null) {\n this._userLogHandler = val;\n }\n\n /**\n * The functions below are all based on the `console` interface\n */\n\n debug(...args: unknown[]): void {\n this._userLogHandler && this._userLogHandler(this, LogLevel.DEBUG, ...args);\n this._logHandler(this, LogLevel.DEBUG, ...args);\n }\n log(...args: unknown[]): void {\n this._userLogHandler &&\n this._userLogHandler(this, LogLevel.VERBOSE, ...args);\n this._logHandler(this, LogLevel.VERBOSE, ...args);\n }\n info(...args: unknown[]): void {\n this._userLogHandler && this._userLogHandler(this, LogLevel.INFO, ...args);\n this._logHandler(this, LogLevel.INFO, ...args);\n }\n warn(...args: unknown[]): void {\n this._userLogHandler && this._userLogHandler(this, LogLevel.WARN, ...args);\n this._logHandler(this, LogLevel.WARN, ...args);\n }\n error(...args: unknown[]): void {\n this._userLogHandler && this._userLogHandler(this, LogLevel.ERROR, ...args);\n this._logHandler(this, LogLevel.ERROR, ...args);\n }\n}\n\nexport function setLogLevel(level: LogLevelString | LogLevel): void {\n instances.forEach(inst => {\n inst.setLogLevel(level);\n });\n}\n\nexport function setUserLogHandler(\n logCallback: LogCallback | null,\n options?: LogOptions\n): void {\n for (const instance of instances) {\n let customLogLevel: LogLevel | null = null;\n if (options && options.level) {\n customLogLevel = levelStringToEnum[options.level];\n }\n if (logCallback === null) {\n instance.userLogHandler = null;\n } else {\n instance.userLogHandler = (\n instance: Logger,\n level: LogLevel,\n ...args: unknown[]\n ) => {\n const message = args\n .map(arg => {\n if (arg == null) {\n return null;\n } else if (typeof arg === 'string') {\n return arg;\n } else if (typeof arg === 'number' || typeof arg === 'boolean') {\n return arg.toString();\n } else if (arg instanceof Error) {\n return arg.message;\n } else {\n try {\n return JSON.stringify(arg);\n } catch (ignored) {\n return null;\n }\n }\n })\n .filter(arg => arg)\n .join(' ');\n if (level >= (customLogLevel ?? instance.logLevel)) {\n logCallback({\n level: LogLevel[level].toLowerCase() as LogLevelString,\n message,\n args,\n type: instance.name\n });\n }\n };\n }\n }\n}\n", "const instanceOfAny = (object, constructors) => constructors.some((c) => object instanceof c);\n\nlet idbProxyableTypes;\nlet cursorAdvanceMethods;\n// This is a function to prevent it throwing up in node environments.\nfunction getIdbProxyableTypes() {\n return (idbProxyableTypes ||\n (idbProxyableTypes = [\n IDBDatabase,\n IDBObjectStore,\n IDBIndex,\n IDBCursor,\n IDBTransaction,\n ]));\n}\n// This is a function to prevent it throwing up in node environments.\nfunction getCursorAdvanceMethods() {\n return (cursorAdvanceMethods ||\n (cursorAdvanceMethods = [\n IDBCursor.prototype.advance,\n IDBCursor.prototype.continue,\n IDBCursor.prototype.continuePrimaryKey,\n ]));\n}\nconst cursorRequestMap = new WeakMap();\nconst transactionDoneMap = new WeakMap();\nconst transactionStoreNamesMap = new WeakMap();\nconst transformCache = new WeakMap();\nconst reverseTransformCache = new WeakMap();\nfunction promisifyRequest(request) {\n const promise = new Promise((resolve, reject) => {\n const unlisten = () => {\n request.removeEventListener('success', success);\n request.removeEventListener('error', error);\n };\n const success = () => {\n resolve(wrap(request.result));\n unlisten();\n };\n const error = () => {\n reject(request.error);\n unlisten();\n };\n request.addEventListener('success', success);\n request.addEventListener('error', error);\n });\n promise\n .then((value) => {\n // Since cursoring reuses the IDBRequest (*sigh*), we cache it for later retrieval\n // (see wrapFunction).\n if (value instanceof IDBCursor) {\n cursorRequestMap.set(value, request);\n }\n // Catching to avoid \"Uncaught Promise exceptions\"\n })\n .catch(() => { });\n // This mapping exists in reverseTransformCache but doesn't doesn't exist in transformCache. This\n // is because we create many promises from a single IDBRequest.\n reverseTransformCache.set(promise, request);\n return promise;\n}\nfunction cacheDonePromiseForTransaction(tx) {\n // Early bail if we've already created a done promise for this transaction.\n if (transactionDoneMap.has(tx))\n return;\n const done = new Promise((resolve, reject) => {\n const unlisten = () => {\n tx.removeEventListener('complete', complete);\n tx.removeEventListener('error', error);\n tx.removeEventListener('abort', error);\n };\n const complete = () => {\n resolve();\n unlisten();\n };\n const error = () => {\n reject(tx.error || new DOMException('AbortError', 'AbortError'));\n unlisten();\n };\n tx.addEventListener('complete', complete);\n tx.addEventListener('error', error);\n tx.addEventListener('abort', error);\n });\n // Cache it for later retrieval.\n transactionDoneMap.set(tx, done);\n}\nlet idbProxyTraps = {\n get(target, prop, receiver) {\n if (target instanceof IDBTransaction) {\n // Special handling for transaction.done.\n if (prop === 'done')\n return transactionDoneMap.get(target);\n // Polyfill for objectStoreNames because of Edge.\n if (prop === 'objectStoreNames') {\n return target.objectStoreNames || transactionStoreNamesMap.get(target);\n }\n // Make tx.store return the only store in the transaction, or undefined if there are many.\n if (prop === 'store') {\n return receiver.objectStoreNames[1]\n ? undefined\n : receiver.objectStore(receiver.objectStoreNames[0]);\n }\n }\n // Else transform whatever we get back.\n return wrap(target[prop]);\n },\n set(target, prop, value) {\n target[prop] = value;\n return true;\n },\n has(target, prop) {\n if (target instanceof IDBTransaction &&\n (prop === 'done' || prop === 'store')) {\n return true;\n }\n return prop in target;\n },\n};\nfunction replaceTraps(callback) {\n idbProxyTraps = callback(idbProxyTraps);\n}\nfunction wrapFunction(func) {\n // Due to expected object equality (which is enforced by the caching in `wrap`), we\n // only create one new func per func.\n // Edge doesn't support objectStoreNames (booo), so we polyfill it here.\n if (func === IDBDatabase.prototype.transaction &&\n !('objectStoreNames' in IDBTransaction.prototype)) {\n return function (storeNames, ...args) {\n const tx = func.call(unwrap(this), storeNames, ...args);\n transactionStoreNamesMap.set(tx, storeNames.sort ? storeNames.sort() : [storeNames]);\n return wrap(tx);\n };\n }\n // Cursor methods are special, as the behaviour is a little more different to standard IDB. In\n // IDB, you advance the cursor and wait for a new 'success' on the IDBRequest that gave you the\n // cursor. It's kinda like a promise that can resolve with many values. That doesn't make sense\n // with real promises, so each advance methods returns a new promise for the cursor object, or\n // undefined if the end of the cursor has been reached.\n if (getCursorAdvanceMethods().includes(func)) {\n return function (...args) {\n // Calling the original function with the proxy as 'this' causes ILLEGAL INVOCATION, so we use\n // the original object.\n func.apply(unwrap(this), args);\n return wrap(cursorRequestMap.get(this));\n };\n }\n return function (...args) {\n // Calling the original function with the proxy as 'this' causes ILLEGAL INVOCATION, so we use\n // the original object.\n return wrap(func.apply(unwrap(this), args));\n };\n}\nfunction transformCachableValue(value) {\n if (typeof value === 'function')\n return wrapFunction(value);\n // This doesn't return, it just creates a 'done' promise for the transaction,\n // which is later returned for transaction.done (see idbObjectHandler).\n if (value instanceof IDBTransaction)\n cacheDonePromiseForTransaction(value);\n if (instanceOfAny(value, getIdbProxyableTypes()))\n return new Proxy(value, idbProxyTraps);\n // Return the same value back if we're not going to transform it.\n return value;\n}\nfunction wrap(value) {\n // We sometimes generate multiple promises from a single IDBRequest (eg when cursoring), because\n // IDB is weird and a single IDBRequest can yield many responses, so these can't be cached.\n if (value instanceof IDBRequest)\n return promisifyRequest(value);\n // If we've already transformed this value before, reuse the transformed value.\n // This is faster, but it also provides object equality.\n if (transformCache.has(value))\n return transformCache.get(value);\n const newValue = transformCachableValue(value);\n // Not all types are transformed.\n // These may be primitive types, so they can't be WeakMap keys.\n if (newValue !== value) {\n transformCache.set(value, newValue);\n reverseTransformCache.set(newValue, value);\n }\n return newValue;\n}\nconst unwrap = (value) => reverseTransformCache.get(value);\n\nexport { reverseTransformCache as a, instanceOfAny as i, replaceTraps as r, unwrap as u, wrap as w };\n", "import { w as wrap, r as replaceTraps } from './wrap-idb-value.js';\nexport { u as unwrap, w as wrap } from './wrap-idb-value.js';\n\n/**\n * Open a database.\n *\n * @param name Name of the database.\n * @param version Schema version.\n * @param callbacks Additional callbacks.\n */\nfunction openDB(name, version, { blocked, upgrade, blocking, terminated } = {}) {\n const request = indexedDB.open(name, version);\n const openPromise = wrap(request);\n if (upgrade) {\n request.addEventListener('upgradeneeded', (event) => {\n upgrade(wrap(request.result), event.oldVersion, event.newVersion, wrap(request.transaction));\n });\n }\n if (blocked)\n request.addEventListener('blocked', () => blocked());\n openPromise\n .then((db) => {\n if (terminated)\n db.addEventListener('close', () => terminated());\n if (blocking)\n db.addEventListener('versionchange', () => blocking());\n })\n .catch(() => { });\n return openPromise;\n}\n/**\n * Delete a database.\n *\n * @param name Name of the database.\n */\nfunction deleteDB(name, { blocked } = {}) {\n const request = indexedDB.deleteDatabase(name);\n if (blocked)\n request.addEventListener('blocked', () => blocked());\n return wrap(request).then(() => undefined);\n}\n\nconst readMethods = ['get', 'getKey', 'getAll', 'getAllKeys', 'count'];\nconst writeMethods = ['put', 'add', 'delete', 'clear'];\nconst cachedMethods = new Map();\nfunction getMethod(target, prop) {\n if (!(target instanceof IDBDatabase &&\n !(prop in target) &&\n typeof prop === 'string')) {\n return;\n }\n if (cachedMethods.get(prop))\n return cachedMethods.get(prop);\n const targetFuncName = prop.replace(/FromIndex$/, '');\n const useIndex = prop !== targetFuncName;\n const isWrite = writeMethods.includes(targetFuncName);\n if (\n // Bail if the target doesn't exist on the target. Eg, getAll isn't in Edge.\n !(targetFuncName in (useIndex ? IDBIndex : IDBObjectStore).prototype) ||\n !(isWrite || readMethods.includes(targetFuncName))) {\n return;\n }\n const method = async function (storeName, ...args) {\n // isWrite ? 'readwrite' : undefined gzipps better, but fails in Edge :(\n const tx = this.transaction(storeName, isWrite ? 'readwrite' : 'readonly');\n let target = tx.store;\n if (useIndex)\n target = target.index(args.shift());\n // Must reject if op rejects.\n // If it's a write operation, must reject if tx.done rejects.\n // Must reject with op rejection first.\n // Must resolve with op value.\n // Must handle both promises (no unhandled rejections)\n return (await Promise.all([\n target[targetFuncName](...args),\n isWrite && tx.done,\n ]))[0];\n };\n cachedMethods.set(prop, method);\n return method;\n}\nreplaceTraps((oldTraps) => ({\n ...oldTraps,\n get: (target, prop, receiver) => getMethod(target, prop) || oldTraps.get(target, prop, receiver),\n has: (target, prop) => !!getMethod(target, prop) || oldTraps.has(target, prop),\n}));\n\nexport { deleteDB, openDB };\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n ComponentContainer,\n ComponentType,\n Provider,\n Name\n} from '@firebase/component';\nimport { PlatformLoggerService, VersionService } from './types';\n\nexport class PlatformLoggerServiceImpl implements PlatformLoggerService {\n constructor(private readonly container: ComponentContainer) {}\n // In initial implementation, this will be called by installations on\n // auth token refresh, and installations will send this string.\n getPlatformInfoString(): string {\n const providers = this.container.getProviders();\n // Loop through providers and get library/version pairs from any that are\n // version components.\n return providers\n .map(provider => {\n if (isVersionServiceProvider(provider)) {\n const service = provider.getImmediate() as VersionService;\n return `${service.library}/${service.version}`;\n } else {\n return null;\n }\n })\n .filter(logString => logString)\n .join(' ');\n }\n}\n/**\n *\n * @param provider check if this provider provides a VersionService\n *\n * NOTE: Using Provider<'app-version'> is a hack to indicate that the provider\n * provides VersionService. The provider is not necessarily a 'app-version'\n * provider.\n */\nfunction isVersionServiceProvider(provider: Provider): boolean {\n const component = provider.getComponent();\n return component?.type === ComponentType.VERSION;\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Logger } from '@firebase/logger';\n\nexport const logger = new Logger('@firebase/app');\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { name as appName } from '../package.json';\nimport { name as appCompatName } from '../../app-compat/package.json';\nimport { name as analyticsCompatName } from '../../../packages/analytics-compat/package.json';\nimport { name as analyticsName } from '../../../packages/analytics/package.json';\nimport { name as appCheckCompatName } from '../../../packages/app-check-compat/package.json';\nimport { name as appCheckName } from '../../../packages/app-check/package.json';\nimport { name as authName } from '../../../packages/auth/package.json';\nimport { name as authCompatName } from '../../../packages/auth-compat/package.json';\nimport { name as databaseName } from '../../../packages/database/package.json';\nimport { name as databaseCompatName } from '../../../packages/database-compat/package.json';\nimport { name as functionsName } from '../../../packages/functions/package.json';\nimport { name as functionsCompatName } from '../../../packages/functions-compat/package.json';\nimport { name as installationsName } from '../../../packages/installations/package.json';\nimport { name as installationsCompatName } from '../../../packages/installations-compat/package.json';\nimport { name as messagingName } from '../../../packages/messaging/package.json';\nimport { name as messagingCompatName } from '../../../packages/messaging-compat/package.json';\nimport { name as performanceName } from '../../../packages/performance/package.json';\nimport { name as performanceCompatName } from '../../../packages/performance-compat/package.json';\nimport { name as remoteConfigName } from '../../../packages/remote-config/package.json';\nimport { name as remoteConfigCompatName } from '../../../packages/remote-config-compat/package.json';\nimport { name as storageName } from '../../../packages/storage/package.json';\nimport { name as storageCompatName } from '../../../packages/storage-compat/package.json';\nimport { name as firestoreName } from '../../../packages/firestore/package.json';\nimport { name as firestoreCompatName } from '../../../packages/firestore-compat/package.json';\nimport { name as packageName } from '../../../packages/firebase/package.json';\n\n/**\n * The default app name\n *\n * @internal\n */\nexport const DEFAULT_ENTRY_NAME = '[DEFAULT]';\n\nexport const PLATFORM_LOG_STRING = {\n [appName]: 'fire-core',\n [appCompatName]: 'fire-core-compat',\n [analyticsName]: 'fire-analytics',\n [analyticsCompatName]: 'fire-analytics-compat',\n [appCheckName]: 'fire-app-check',\n [appCheckCompatName]: 'fire-app-check-compat',\n [authName]: 'fire-auth',\n [authCompatName]: 'fire-auth-compat',\n [databaseName]: 'fire-rtdb',\n [databaseCompatName]: 'fire-rtdb-compat',\n [functionsName]: 'fire-fn',\n [functionsCompatName]: 'fire-fn-compat',\n [installationsName]: 'fire-iid',\n [installationsCompatName]: 'fire-iid-compat',\n [messagingName]: 'fire-fcm',\n [messagingCompatName]: 'fire-fcm-compat',\n [performanceName]: 'fire-perf',\n [performanceCompatName]: 'fire-perf-compat',\n [remoteConfigName]: 'fire-rc',\n [remoteConfigCompatName]: 'fire-rc-compat',\n [storageName]: 'fire-gcs',\n [storageCompatName]: 'fire-gcs-compat',\n [firestoreName]: 'fire-fst',\n [firestoreCompatName]: 'fire-fst-compat',\n 'fire-js': 'fire-js', // Platform identifier for JS SDK.\n [packageName]: 'fire-js-all'\n} as const;\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { FirebaseApp } from './public-types';\nimport { Component, Provider, Name } from '@firebase/component';\nimport { logger } from './logger';\nimport { DEFAULT_ENTRY_NAME } from './constants';\nimport { FirebaseAppImpl } from './firebaseApp';\n\n/**\n * @internal\n */\nexport const _apps = new Map();\n\n/**\n * Registered components.\n *\n * @internal\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport const _components = new Map>();\n\n/**\n * @param component - the component being added to this app's container\n *\n * @internal\n */\nexport function _addComponent(\n app: FirebaseApp,\n component: Component\n): void {\n try {\n (app as FirebaseAppImpl).container.addComponent(component);\n } catch (e) {\n logger.debug(\n `Component ${component.name} failed to register with FirebaseApp ${app.name}`,\n e\n );\n }\n}\n\n/**\n *\n * @internal\n */\nexport function _addOrOverwriteComponent(\n app: FirebaseApp,\n component: Component\n): void {\n (app as FirebaseAppImpl).container.addOrOverwriteComponent(component);\n}\n\n/**\n *\n * @param component - the component to register\n * @returns whether or not the component is registered successfully\n *\n * @internal\n */\nexport function _registerComponent(\n component: Component\n): boolean {\n const componentName = component.name;\n if (_components.has(componentName)) {\n logger.debug(\n `There were multiple attempts to register component ${componentName}.`\n );\n\n return false;\n }\n\n _components.set(componentName, component);\n\n // add the component to existing app instances\n for (const app of _apps.values()) {\n _addComponent(app as FirebaseAppImpl, component);\n }\n\n return true;\n}\n\n/**\n *\n * @param app - FirebaseApp instance\n * @param name - service name\n *\n * @returns the provider for the service with the matching name\n *\n * @internal\n */\nexport function _getProvider(\n app: FirebaseApp,\n name: T\n): Provider {\n const heartbeatController = (app as FirebaseAppImpl).container\n .getProvider('heartbeat')\n .getImmediate({ optional: true });\n if (heartbeatController) {\n void heartbeatController.triggerHeartbeat();\n }\n return (app as FirebaseAppImpl).container.getProvider(name);\n}\n\n/**\n *\n * @param app - FirebaseApp instance\n * @param name - service name\n * @param instanceIdentifier - service instance identifier in case the service supports multiple instances\n *\n * @internal\n */\nexport function _removeServiceInstance(\n app: FirebaseApp,\n name: T,\n instanceIdentifier: string = DEFAULT_ENTRY_NAME\n): void {\n _getProvider(app, name).clearInstance(instanceIdentifier);\n}\n\n/**\n * Test only\n *\n * @internal\n */\nexport function _clearComponents(): void {\n _components.clear();\n}\n\n/**\n * Exported in order to be used in app-compat package\n */\nexport { DEFAULT_ENTRY_NAME as _DEFAULT_ENTRY_NAME };\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ErrorFactory, ErrorMap } from '@firebase/util';\n\nexport const enum AppError {\n NO_APP = 'no-app',\n BAD_APP_NAME = 'bad-app-name',\n DUPLICATE_APP = 'duplicate-app',\n APP_DELETED = 'app-deleted',\n INVALID_APP_ARGUMENT = 'invalid-app-argument',\n INVALID_LOG_ARGUMENT = 'invalid-log-argument',\n IDB_OPEN = 'idb-open',\n IDB_GET = 'idb-get',\n IDB_WRITE = 'idb-set',\n IDB_DELETE = 'idb-delete'\n}\n\nconst ERRORS: ErrorMap = {\n [AppError.NO_APP]:\n \"No Firebase App '{$appName}' has been created - \" +\n 'call Firebase App.initializeApp()',\n [AppError.BAD_APP_NAME]: \"Illegal App name: '{$appName}\",\n [AppError.DUPLICATE_APP]:\n \"Firebase App named '{$appName}' already exists with different options or config\",\n [AppError.APP_DELETED]: \"Firebase App named '{$appName}' already deleted\",\n [AppError.INVALID_APP_ARGUMENT]:\n 'firebase.{$appName}() takes either no argument or a ' +\n 'Firebase App instance.',\n [AppError.INVALID_LOG_ARGUMENT]:\n 'First argument to `onLog` must be null or a function.',\n [AppError.IDB_OPEN]:\n 'Error thrown when opening IndexedDB. Original error: {$originalErrorMessage}.',\n [AppError.IDB_GET]:\n 'Error thrown when reading from IndexedDB. Original error: {$originalErrorMessage}.',\n [AppError.IDB_WRITE]:\n 'Error thrown when writing to IndexedDB. Original error: {$originalErrorMessage}.',\n [AppError.IDB_DELETE]:\n 'Error thrown when deleting from IndexedDB. Original error: {$originalErrorMessage}.'\n};\n\ninterface ErrorParams {\n [AppError.NO_APP]: { appName: string };\n [AppError.BAD_APP_NAME]: { appName: string };\n [AppError.DUPLICATE_APP]: { appName: string };\n [AppError.APP_DELETED]: { appName: string };\n [AppError.INVALID_APP_ARGUMENT]: { appName: string };\n [AppError.IDB_OPEN]: { originalErrorMessage?: string };\n [AppError.IDB_GET]: { originalErrorMessage?: string };\n [AppError.IDB_WRITE]: { originalErrorMessage?: string };\n [AppError.IDB_DELETE]: { originalErrorMessage?: string };\n}\n\nexport const ERROR_FACTORY = new ErrorFactory(\n 'app',\n 'Firebase',\n ERRORS\n);\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n FirebaseApp,\n FirebaseOptions,\n FirebaseAppSettings\n} from './public-types';\nimport {\n ComponentContainer,\n Component,\n ComponentType\n} from '@firebase/component';\nimport { ERROR_FACTORY, AppError } from './errors';\n\nexport class FirebaseAppImpl implements FirebaseApp {\n private readonly _options: FirebaseOptions;\n private readonly _name: string;\n /**\n * Original config values passed in as a constructor parameter.\n * It is only used to compare with another config object to support idempotent initializeApp().\n *\n * Updating automaticDataCollectionEnabled on the App instance will not change its value in _config.\n */\n private readonly _config: Required;\n private _automaticDataCollectionEnabled: boolean;\n private _isDeleted = false;\n private readonly _container: ComponentContainer;\n\n constructor(\n options: FirebaseOptions,\n config: Required,\n container: ComponentContainer\n ) {\n this._options = { ...options };\n this._config = { ...config };\n this._name = config.name;\n this._automaticDataCollectionEnabled =\n config.automaticDataCollectionEnabled;\n this._container = container;\n this.container.addComponent(\n new Component('app', () => this, ComponentType.PUBLIC)\n );\n }\n\n get automaticDataCollectionEnabled(): boolean {\n this.checkDestroyed();\n return this._automaticDataCollectionEnabled;\n }\n\n set automaticDataCollectionEnabled(val: boolean) {\n this.checkDestroyed();\n this._automaticDataCollectionEnabled = val;\n }\n\n get name(): string {\n this.checkDestroyed();\n return this._name;\n }\n\n get options(): FirebaseOptions {\n this.checkDestroyed();\n return this._options;\n }\n\n get config(): Required {\n this.checkDestroyed();\n return this._config;\n }\n\n get container(): ComponentContainer {\n return this._container;\n }\n\n get isDeleted(): boolean {\n return this._isDeleted;\n }\n\n set isDeleted(val: boolean) {\n this._isDeleted = val;\n }\n\n /**\n * This function will throw an Error if the App has already been deleted -\n * use before performing API actions on the App.\n */\n private checkDestroyed(): void {\n if (this.isDeleted) {\n throw ERROR_FACTORY.create(AppError.APP_DELETED, { appName: this._name });\n }\n }\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n FirebaseApp,\n FirebaseOptions,\n FirebaseAppSettings\n} from './public-types';\nimport { DEFAULT_ENTRY_NAME, PLATFORM_LOG_STRING } from './constants';\nimport { ERROR_FACTORY, AppError } from './errors';\nimport {\n ComponentContainer,\n Component,\n Name,\n ComponentType\n} from '@firebase/component';\nimport { version } from '../../firebase/package.json';\nimport { FirebaseAppImpl } from './firebaseApp';\nimport { _apps, _components, _registerComponent } from './internal';\nimport { logger } from './logger';\nimport {\n LogLevelString,\n setLogLevel as setLogLevelImpl,\n LogCallback,\n LogOptions,\n setUserLogHandler\n} from '@firebase/logger';\nimport { deepEqual } from '@firebase/util';\n\nexport { FirebaseError } from '@firebase/util';\n\n/**\n * The current SDK version.\n *\n * @public\n */\nexport const SDK_VERSION = version;\n\n/**\n * Creates and initializes a {@link @firebase/app#FirebaseApp} instance.\n *\n * See\n * {@link\n * https://firebase.google.com/docs/web/setup#add_firebase_to_your_app\n * | Add Firebase to your app} and\n * {@link\n * https://firebase.google.com/docs/web/setup#multiple-projects\n * | Initialize multiple projects} for detailed documentation.\n *\n * @example\n * ```javascript\n *\n * // Initialize default app\n * // Retrieve your own options values by adding a web app on\n * // https://console.firebase.google.com\n * initializeApp({\n * apiKey: \"AIza....\", // Auth / General Use\n * authDomain: \"YOUR_APP.firebaseapp.com\", // Auth with popup/redirect\n * databaseURL: \"https://YOUR_APP.firebaseio.com\", // Realtime Database\n * storageBucket: \"YOUR_APP.appspot.com\", // Storage\n * messagingSenderId: \"123456789\" // Cloud Messaging\n * });\n * ```\n *\n * @example\n * ```javascript\n *\n * // Initialize another app\n * const otherApp = initializeApp({\n * databaseURL: \"https://.firebaseio.com\",\n * storageBucket: \".appspot.com\"\n * }, \"otherApp\");\n * ```\n *\n * @param options - Options to configure the app's services.\n * @param name - Optional name of the app to initialize. If no name\n * is provided, the default is `\"[DEFAULT]\"`.\n *\n * @returns The initialized app.\n *\n * @public\n */\nexport function initializeApp(\n options: FirebaseOptions,\n name?: string\n): FirebaseApp;\n/**\n * Creates and initializes a FirebaseApp instance.\n *\n * @param options - Options to configure the app's services.\n * @param config - FirebaseApp Configuration\n *\n * @public\n */\nexport function initializeApp(\n options: FirebaseOptions,\n config?: FirebaseAppSettings\n): FirebaseApp;\nexport function initializeApp(\n options: FirebaseOptions,\n rawConfig = {}\n): FirebaseApp {\n if (typeof rawConfig !== 'object') {\n const name = rawConfig;\n rawConfig = { name };\n }\n\n const config: Required = {\n name: DEFAULT_ENTRY_NAME,\n automaticDataCollectionEnabled: false,\n ...rawConfig\n };\n const name = config.name;\n\n if (typeof name !== 'string' || !name) {\n throw ERROR_FACTORY.create(AppError.BAD_APP_NAME, {\n appName: String(name)\n });\n }\n\n const existingApp = _apps.get(name) as FirebaseAppImpl;\n if (existingApp) {\n // return the existing app if options and config deep equal the ones in the existing app.\n if (\n deepEqual(options, existingApp.options) &&\n deepEqual(config, existingApp.config)\n ) {\n return existingApp;\n } else {\n throw ERROR_FACTORY.create(AppError.DUPLICATE_APP, { appName: name });\n }\n }\n\n const container = new ComponentContainer(name);\n for (const component of _components.values()) {\n container.addComponent(component);\n }\n\n const newApp = new FirebaseAppImpl(options, config, container);\n\n _apps.set(name, newApp);\n\n return newApp;\n}\n\n/**\n * Retrieves a {@link @firebase/app#FirebaseApp} instance.\n *\n * When called with no arguments, the default app is returned. When an app name\n * is provided, the app corresponding to that name is returned.\n *\n * An exception is thrown if the app being retrieved has not yet been\n * initialized.\n *\n * @example\n * ```javascript\n * // Return the default app\n * const app = getApp();\n * ```\n *\n * @example\n * ```javascript\n * // Return a named app\n * const otherApp = getApp(\"otherApp\");\n * ```\n *\n * @param name - Optional name of the app to return. If no name is\n * provided, the default is `\"[DEFAULT]\"`.\n *\n * @returns The app corresponding to the provided app name.\n * If no app name is provided, the default app is returned.\n *\n * @public\n */\nexport function getApp(name: string = DEFAULT_ENTRY_NAME): FirebaseApp {\n const app = _apps.get(name);\n if (!app) {\n throw ERROR_FACTORY.create(AppError.NO_APP, { appName: name });\n }\n\n return app;\n}\n\n/**\n * A (read-only) array of all initialized apps.\n * @public\n */\nexport function getApps(): FirebaseApp[] {\n return Array.from(_apps.values());\n}\n\n/**\n * Renders this app unusable and frees the resources of all associated\n * services.\n *\n * @example\n * ```javascript\n * deleteApp(app)\n * .then(function() {\n * console.log(\"App deleted successfully\");\n * })\n * .catch(function(error) {\n * console.log(\"Error deleting app:\", error);\n * });\n * ```\n *\n * @public\n */\nexport async function deleteApp(app: FirebaseApp): Promise {\n const name = app.name;\n if (_apps.has(name)) {\n _apps.delete(name);\n await Promise.all(\n (app as FirebaseAppImpl).container\n .getProviders()\n .map(provider => provider.delete())\n );\n (app as FirebaseAppImpl).isDeleted = true;\n }\n}\n\n/**\n * Registers a library's name and version for platform logging purposes.\n * @param library - Name of 1p or 3p library (e.g. firestore, angularfire)\n * @param version - Current version of that library.\n * @param variant - Bundle variant, e.g., node, rn, etc.\n *\n * @public\n */\nexport function registerVersion(\n libraryKeyOrName: string,\n version: string,\n variant?: string\n): void {\n // TODO: We can use this check to whitelist strings when/if we set up\n // a good whitelist system.\n let library = PLATFORM_LOG_STRING[libraryKeyOrName] ?? libraryKeyOrName;\n if (variant) {\n library += `-${variant}`;\n }\n const libraryMismatch = library.match(/\\s|\\//);\n const versionMismatch = version.match(/\\s|\\//);\n if (libraryMismatch || versionMismatch) {\n const warning = [\n `Unable to register library \"${library}\" with version \"${version}\":`\n ];\n if (libraryMismatch) {\n warning.push(\n `library name \"${library}\" contains illegal characters (whitespace or \"/\")`\n );\n }\n if (libraryMismatch && versionMismatch) {\n warning.push('and');\n }\n if (versionMismatch) {\n warning.push(\n `version name \"${version}\" contains illegal characters (whitespace or \"/\")`\n );\n }\n logger.warn(warning.join(' '));\n return;\n }\n _registerComponent(\n new Component(\n `${library}-version` as Name,\n () => ({ library, version }),\n ComponentType.VERSION\n )\n );\n}\n\n/**\n * Sets log handler for all Firebase SDKs.\n * @param logCallback - An optional custom log handler that executes user code whenever\n * the Firebase SDK makes a logging call.\n *\n * @public\n */\nexport function onLog(\n logCallback: LogCallback | null,\n options?: LogOptions\n): void {\n if (logCallback !== null && typeof logCallback !== 'function') {\n throw ERROR_FACTORY.create(AppError.INVALID_LOG_ARGUMENT);\n }\n setUserLogHandler(logCallback, options);\n}\n\n/**\n * Sets log level for all Firebase SDKs.\n *\n * All of the log types above the current log level are captured (i.e. if\n * you set the log level to `info`, errors are logged, but `debug` and\n * `verbose` logs are not).\n *\n * @public\n */\nexport function setLogLevel(logLevel: LogLevelString): void {\n setLogLevelImpl(logLevel);\n}\n", "/**\n * @license\n * Copyright 2021 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { FirebaseError } from '@firebase/util';\nimport { DBSchema, openDB, IDBPDatabase } from 'idb';\nimport { AppError, ERROR_FACTORY } from './errors';\nimport { FirebaseApp } from './public-types';\nimport { HeartbeatsInIndexedDB } from './types';\nimport { logger } from './logger';\n\nconst DB_NAME = 'firebase-heartbeat-database';\nconst DB_VERSION = 1;\nconst STORE_NAME = 'firebase-heartbeat-store';\n\ninterface AppDB extends DBSchema {\n 'firebase-heartbeat-store': {\n key: string;\n value: HeartbeatsInIndexedDB;\n };\n}\n\nlet dbPromise: Promise> | null = null;\nfunction getDbPromise(): Promise> {\n if (!dbPromise) {\n dbPromise = openDB(DB_NAME, DB_VERSION, {\n upgrade: (db, oldVersion) => {\n // We don't use 'break' in this switch statement, the fall-through\n // behavior is what we want, because if there are multiple versions between\n // the old version and the current version, we want ALL the migrations\n // that correspond to those versions to run, not only the last one.\n // eslint-disable-next-line default-case\n switch (oldVersion) {\n case 0:\n db.createObjectStore(STORE_NAME);\n }\n }\n }).catch(e => {\n throw ERROR_FACTORY.create(AppError.IDB_OPEN, {\n originalErrorMessage: e.message\n });\n });\n }\n return dbPromise;\n}\n\nexport async function readHeartbeatsFromIndexedDB(\n app: FirebaseApp\n): Promise {\n try {\n const db = await getDbPromise();\n return db\n .transaction(STORE_NAME)\n .objectStore(STORE_NAME)\n .get(computeKey(app)) as Promise;\n } catch (e) {\n if (e instanceof FirebaseError) {\n logger.warn(e.message);\n } else {\n const idbGetError = ERROR_FACTORY.create(AppError.IDB_GET, {\n originalErrorMessage: (e as Error)?.message\n });\n logger.warn(idbGetError.message);\n }\n }\n}\n\nexport async function writeHeartbeatsToIndexedDB(\n app: FirebaseApp,\n heartbeatObject: HeartbeatsInIndexedDB\n): Promise {\n try {\n const db = await getDbPromise();\n const tx = db.transaction(STORE_NAME, 'readwrite');\n const objectStore = tx.objectStore(STORE_NAME);\n await objectStore.put(heartbeatObject, computeKey(app));\n return tx.done;\n } catch (e) {\n if (e instanceof FirebaseError) {\n logger.warn(e.message);\n } else {\n const idbGetError = ERROR_FACTORY.create(AppError.IDB_WRITE, {\n originalErrorMessage: (e as Error)?.message\n });\n logger.warn(idbGetError.message);\n }\n }\n}\n\nfunction computeKey(app: FirebaseApp): string {\n return `${app.name}!${app.options.appId}`;\n}\n", "/**\n * @license\n * Copyright 2021 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ComponentContainer } from '@firebase/component';\nimport {\n base64urlEncodeWithoutPadding,\n isIndexedDBAvailable,\n validateIndexedDBOpenable\n} from '@firebase/util';\nimport {\n readHeartbeatsFromIndexedDB,\n writeHeartbeatsToIndexedDB\n} from './indexeddb';\nimport { FirebaseApp } from './public-types';\nimport {\n HeartbeatsByUserAgent,\n HeartbeatService,\n HeartbeatsInIndexedDB,\n HeartbeatStorage,\n SingleDateHeartbeat\n} from './types';\n\nconst MAX_HEADER_BYTES = 1024;\n// 30 days\nconst STORED_HEARTBEAT_RETENTION_MAX_MILLIS = 30 * 24 * 60 * 60 * 1000;\n\nexport class HeartbeatServiceImpl implements HeartbeatService {\n /**\n * The persistence layer for heartbeats\n * Leave public for easier testing.\n */\n _storage: HeartbeatStorageImpl;\n\n /**\n * In-memory cache for heartbeats, used by getHeartbeatsHeader() to generate\n * the header string.\n * Stores one record per date. This will be consolidated into the standard\n * format of one record per user agent string before being sent as a header.\n * Populated from indexedDB when the controller is instantiated and should\n * be kept in sync with indexedDB.\n * Leave public for easier testing.\n */\n _heartbeatsCache: HeartbeatsInIndexedDB | null = null;\n\n /**\n * the initialization promise for populating heartbeatCache.\n * If getHeartbeatsHeader() is called before the promise resolves\n * (hearbeatsCache == null), it should wait for this promise\n * Leave public for easier testing.\n */\n _heartbeatsCachePromise: Promise;\n constructor(private readonly container: ComponentContainer) {\n const app = this.container.getProvider('app').getImmediate();\n this._storage = new HeartbeatStorageImpl(app);\n this._heartbeatsCachePromise = this._storage.read().then(result => {\n this._heartbeatsCache = result;\n return result;\n });\n }\n\n /**\n * Called to report a heartbeat. The function will generate\n * a HeartbeatsByUserAgent object, update heartbeatsCache, and persist it\n * to IndexedDB.\n * Note that we only store one heartbeat per day. So if a heartbeat for today is\n * already logged, subsequent calls to this function in the same day will be ignored.\n */\n async triggerHeartbeat(): Promise {\n const platformLogger = this.container\n .getProvider('platform-logger')\n .getImmediate();\n\n // This is the \"Firebase user agent\" string from the platform logger\n // service, not the browser user agent.\n const agent = platformLogger.getPlatformInfoString();\n const date = getUTCDateString();\n if (this._heartbeatsCache === null) {\n this._heartbeatsCache = await this._heartbeatsCachePromise;\n }\n // Do not store a heartbeat if one is already stored for this day\n // or if a header has already been sent today.\n if (\n this._heartbeatsCache.lastSentHeartbeatDate === date ||\n this._heartbeatsCache.heartbeats.some(\n singleDateHeartbeat => singleDateHeartbeat.date === date\n )\n ) {\n return;\n } else {\n // There is no entry for this date. Create one.\n this._heartbeatsCache.heartbeats.push({ date, agent });\n }\n // Remove entries older than 30 days.\n this._heartbeatsCache.heartbeats = this._heartbeatsCache.heartbeats.filter(\n singleDateHeartbeat => {\n const hbTimestamp = new Date(singleDateHeartbeat.date).valueOf();\n const now = Date.now();\n return now - hbTimestamp <= STORED_HEARTBEAT_RETENTION_MAX_MILLIS;\n }\n );\n return this._storage.overwrite(this._heartbeatsCache);\n }\n\n /**\n * Returns a base64 encoded string which can be attached to the heartbeat-specific header directly.\n * It also clears all heartbeats from memory as well as in IndexedDB.\n *\n * NOTE: Consuming product SDKs should not send the header if this method\n * returns an empty string.\n */\n async getHeartbeatsHeader(): Promise {\n if (this._heartbeatsCache === null) {\n await this._heartbeatsCachePromise;\n }\n // If it's still null or the array is empty, there is no data to send.\n if (\n this._heartbeatsCache === null ||\n this._heartbeatsCache.heartbeats.length === 0\n ) {\n return '';\n }\n const date = getUTCDateString();\n // Extract as many heartbeats from the cache as will fit under the size limit.\n const { heartbeatsToSend, unsentEntries } = extractHeartbeatsForHeader(\n this._heartbeatsCache.heartbeats\n );\n const headerString = base64urlEncodeWithoutPadding(\n JSON.stringify({ version: 2, heartbeats: heartbeatsToSend })\n );\n // Store last sent date to prevent another being logged/sent for the same day.\n this._heartbeatsCache.lastSentHeartbeatDate = date;\n if (unsentEntries.length > 0) {\n // Store any unsent entries if they exist.\n this._heartbeatsCache.heartbeats = unsentEntries;\n // This seems more likely than emptying the array (below) to lead to some odd state\n // since the cache isn't empty and this will be called again on the next request,\n // and is probably safest if we await it.\n await this._storage.overwrite(this._heartbeatsCache);\n } else {\n this._heartbeatsCache.heartbeats = [];\n // Do not wait for this, to reduce latency.\n void this._storage.overwrite(this._heartbeatsCache);\n }\n return headerString;\n }\n}\n\nfunction getUTCDateString(): string {\n const today = new Date();\n // Returns date format 'YYYY-MM-DD'\n return today.toISOString().substring(0, 10);\n}\n\nexport function extractHeartbeatsForHeader(\n heartbeatsCache: SingleDateHeartbeat[],\n maxSize = MAX_HEADER_BYTES\n): {\n heartbeatsToSend: HeartbeatsByUserAgent[];\n unsentEntries: SingleDateHeartbeat[];\n} {\n // Heartbeats grouped by user agent in the standard format to be sent in\n // the header.\n const heartbeatsToSend: HeartbeatsByUserAgent[] = [];\n // Single date format heartbeats that are not sent.\n let unsentEntries = heartbeatsCache.slice();\n for (const singleDateHeartbeat of heartbeatsCache) {\n // Look for an existing entry with the same user agent.\n const heartbeatEntry = heartbeatsToSend.find(\n hb => hb.agent === singleDateHeartbeat.agent\n );\n if (!heartbeatEntry) {\n // If no entry for this user agent exists, create one.\n heartbeatsToSend.push({\n agent: singleDateHeartbeat.agent,\n dates: [singleDateHeartbeat.date]\n });\n if (countBytes(heartbeatsToSend) > maxSize) {\n // If the header would exceed max size, remove the added heartbeat\n // entry and stop adding to the header.\n heartbeatsToSend.pop();\n break;\n }\n } else {\n heartbeatEntry.dates.push(singleDateHeartbeat.date);\n // If the header would exceed max size, remove the added date\n // and stop adding to the header.\n if (countBytes(heartbeatsToSend) > maxSize) {\n heartbeatEntry.dates.pop();\n break;\n }\n }\n // Pop unsent entry from queue. (Skipped if adding the entry exceeded\n // quota and the loop breaks early.)\n unsentEntries = unsentEntries.slice(1);\n }\n return {\n heartbeatsToSend,\n unsentEntries\n };\n}\n\nexport class HeartbeatStorageImpl implements HeartbeatStorage {\n private _canUseIndexedDBPromise: Promise;\n constructor(public app: FirebaseApp) {\n this._canUseIndexedDBPromise = this.runIndexedDBEnvironmentCheck();\n }\n async runIndexedDBEnvironmentCheck(): Promise {\n if (!isIndexedDBAvailable()) {\n return false;\n } else {\n return validateIndexedDBOpenable()\n .then(() => true)\n .catch(() => false);\n }\n }\n /**\n * Read all heartbeats.\n */\n async read(): Promise {\n const canUseIndexedDB = await this._canUseIndexedDBPromise;\n if (!canUseIndexedDB) {\n return { heartbeats: [] };\n } else {\n const idbHeartbeatObject = await readHeartbeatsFromIndexedDB(this.app);\n return idbHeartbeatObject || { heartbeats: [] };\n }\n }\n // overwrite the storage with the provided heartbeats\n async overwrite(heartbeatsObject: HeartbeatsInIndexedDB): Promise {\n const canUseIndexedDB = await this._canUseIndexedDBPromise;\n if (!canUseIndexedDB) {\n return;\n } else {\n const existingHeartbeatsObject = await this.read();\n return writeHeartbeatsToIndexedDB(this.app, {\n lastSentHeartbeatDate:\n heartbeatsObject.lastSentHeartbeatDate ??\n existingHeartbeatsObject.lastSentHeartbeatDate,\n heartbeats: heartbeatsObject.heartbeats\n });\n }\n }\n // add heartbeats\n async add(heartbeatsObject: HeartbeatsInIndexedDB): Promise {\n const canUseIndexedDB = await this._canUseIndexedDBPromise;\n if (!canUseIndexedDB) {\n return;\n } else {\n const existingHeartbeatsObject = await this.read();\n return writeHeartbeatsToIndexedDB(this.app, {\n lastSentHeartbeatDate:\n heartbeatsObject.lastSentHeartbeatDate ??\n existingHeartbeatsObject.lastSentHeartbeatDate,\n heartbeats: [\n ...existingHeartbeatsObject.heartbeats,\n ...heartbeatsObject.heartbeats\n ]\n });\n }\n }\n}\n\n/**\n * Calculate bytes of a HeartbeatsByUserAgent array after being wrapped\n * in a platform logging header JSON object, stringified, and converted\n * to base 64.\n */\nexport function countBytes(heartbeatsCache: HeartbeatsByUserAgent[]): number {\n // base64 has a restricted set of characters, all of which should be 1 byte.\n return base64urlEncodeWithoutPadding(\n // heartbeatsCache wrapper properties\n JSON.stringify({ version: 2, heartbeats: heartbeatsCache })\n ).length;\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Component, ComponentType } from '@firebase/component';\nimport { PlatformLoggerServiceImpl } from './platformLoggerService';\nimport { name, version } from '../package.json';\nimport { _registerComponent } from './internal';\nimport { registerVersion } from './api';\nimport { HeartbeatServiceImpl } from './heartbeatService';\n\nexport function registerCoreComponents(variant?: string): void {\n _registerComponent(\n new Component(\n 'platform-logger',\n container => new PlatformLoggerServiceImpl(container),\n ComponentType.PRIVATE\n )\n );\n _registerComponent(\n new Component(\n 'heartbeat',\n container => new HeartbeatServiceImpl(container),\n ComponentType.PRIVATE\n )\n );\n\n // Register `app` package.\n registerVersion(name, version, variant);\n // BUILD_TARGET will be replaced by values like esm5, esm2017, cjs5, etc during the compilation\n registerVersion(name, version, '__BUILD_TARGET__');\n // Register platform SDK identifier (no version).\n registerVersion('fire-js', '');\n}\n", "/**\n * Firebase App\n *\n * @remarks This package coordinates the communication between the different Firebase components\n * @packageDocumentation\n */\n\n/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { registerCoreComponents } from './registerCoreComponents';\n\nexport * from './api';\nexport * from './internal';\nexport * from './public-types';\n\nregisterCoreComponents('__RUNTIME_ENV__');\n", "/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { registerVersion } from '@firebase/app';\nimport { name, version } from '../package.json';\n\nregisterVersion(name, version, 'app');\nexport * from '@firebase/app';\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { version } from '../../package.json';\n\nexport const PENDING_TIMEOUT_MS = 10000;\n\nexport const PACKAGE_VERSION = `w:${version}`;\nexport const INTERNAL_AUTH_VERSION = 'FIS_v2';\n\nexport const INSTALLATIONS_API_URL =\n 'https://firebaseinstallations.googleapis.com/v1';\n\nexport const TOKEN_EXPIRATION_BUFFER = 60 * 60 * 1000; // One hour\n\nexport const SERVICE = 'installations';\nexport const SERVICE_NAME = 'Installations';\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ErrorFactory, FirebaseError } from '@firebase/util';\nimport { SERVICE, SERVICE_NAME } from './constants';\n\nexport const enum ErrorCode {\n MISSING_APP_CONFIG_VALUES = 'missing-app-config-values',\n NOT_REGISTERED = 'not-registered',\n INSTALLATION_NOT_FOUND = 'installation-not-found',\n REQUEST_FAILED = 'request-failed',\n APP_OFFLINE = 'app-offline',\n DELETE_PENDING_REGISTRATION = 'delete-pending-registration'\n}\n\nconst ERROR_DESCRIPTION_MAP: { readonly [key in ErrorCode]: string } = {\n [ErrorCode.MISSING_APP_CONFIG_VALUES]:\n 'Missing App configuration value: \"{$valueName}\"',\n [ErrorCode.NOT_REGISTERED]: 'Firebase Installation is not registered.',\n [ErrorCode.INSTALLATION_NOT_FOUND]: 'Firebase Installation not found.',\n [ErrorCode.REQUEST_FAILED]:\n '{$requestName} request failed with error \"{$serverCode} {$serverStatus}: {$serverMessage}\"',\n [ErrorCode.APP_OFFLINE]: 'Could not process request. Application offline.',\n [ErrorCode.DELETE_PENDING_REGISTRATION]:\n \"Can't delete installation while there is a pending registration request.\"\n};\n\ninterface ErrorParams {\n [ErrorCode.MISSING_APP_CONFIG_VALUES]: {\n valueName: string;\n };\n [ErrorCode.REQUEST_FAILED]: {\n requestName: string;\n [index: string]: string | number; // to make Typescript 3.8 happy\n } & ServerErrorData;\n}\n\nexport const ERROR_FACTORY = new ErrorFactory(\n SERVICE,\n SERVICE_NAME,\n ERROR_DESCRIPTION_MAP\n);\n\nexport interface ServerErrorData {\n serverCode: number;\n serverMessage: string;\n serverStatus: string;\n}\n\nexport type ServerError = FirebaseError & { customData: ServerErrorData };\n\n/** Returns true if error is a FirebaseError that is based on an error from the server. */\nexport function isServerError(error: unknown): error is ServerError {\n return (\n error instanceof FirebaseError &&\n error.code.includes(ErrorCode.REQUEST_FAILED)\n );\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { FirebaseError } from '@firebase/util';\nimport { GenerateAuthTokenResponse } from '../interfaces/api-response';\nimport {\n CompletedAuthToken,\n RegisteredInstallationEntry,\n RequestStatus\n} from '../interfaces/installation-entry';\nimport {\n INSTALLATIONS_API_URL,\n INTERNAL_AUTH_VERSION\n} from '../util/constants';\nimport { ERROR_FACTORY, ErrorCode } from '../util/errors';\nimport { AppConfig } from '../interfaces/installation-impl';\n\nexport function getInstallationsEndpoint({ projectId }: AppConfig): string {\n return `${INSTALLATIONS_API_URL}/projects/${projectId}/installations`;\n}\n\nexport function extractAuthTokenInfoFromResponse(\n response: GenerateAuthTokenResponse\n): CompletedAuthToken {\n return {\n token: response.token,\n requestStatus: RequestStatus.COMPLETED,\n expiresIn: getExpiresInFromResponseExpiresIn(response.expiresIn),\n creationTime: Date.now()\n };\n}\n\nexport async function getErrorFromResponse(\n requestName: string,\n response: Response\n): Promise {\n const responseJson: ErrorResponse = await response.json();\n const errorData = responseJson.error;\n return ERROR_FACTORY.create(ErrorCode.REQUEST_FAILED, {\n requestName,\n serverCode: errorData.code,\n serverMessage: errorData.message,\n serverStatus: errorData.status\n });\n}\n\nexport function getHeaders({ apiKey }: AppConfig): Headers {\n return new Headers({\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n 'x-goog-api-key': apiKey\n });\n}\n\nexport function getHeadersWithAuth(\n appConfig: AppConfig,\n { refreshToken }: RegisteredInstallationEntry\n): Headers {\n const headers = getHeaders(appConfig);\n headers.append('Authorization', getAuthorizationHeader(refreshToken));\n return headers;\n}\n\nexport interface ErrorResponse {\n error: {\n code: number;\n message: string;\n status: string;\n };\n}\n\n/**\n * Calls the passed in fetch wrapper and returns the response.\n * If the returned response has a status of 5xx, re-runs the function once and\n * returns the response.\n */\nexport async function retryIfServerError(\n fn: () => Promise\n): Promise {\n const result = await fn();\n\n if (result.status >= 500 && result.status < 600) {\n // Internal Server Error. Retry request.\n return fn();\n }\n\n return result;\n}\n\nfunction getExpiresInFromResponseExpiresIn(responseExpiresIn: string): number {\n // This works because the server will never respond with fractions of a second.\n return Number(responseExpiresIn.replace('s', '000'));\n}\n\nfunction getAuthorizationHeader(refreshToken: string): string {\n return `${INTERNAL_AUTH_VERSION} ${refreshToken}`;\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { CreateInstallationResponse } from '../interfaces/api-response';\nimport {\n InProgressInstallationEntry,\n RegisteredInstallationEntry,\n RequestStatus\n} from '../interfaces/installation-entry';\nimport { INTERNAL_AUTH_VERSION, PACKAGE_VERSION } from '../util/constants';\nimport {\n extractAuthTokenInfoFromResponse,\n getErrorFromResponse,\n getHeaders,\n getInstallationsEndpoint,\n retryIfServerError\n} from './common';\nimport { FirebaseInstallationsImpl } from '../interfaces/installation-impl';\n\nexport async function createInstallationRequest(\n { appConfig, heartbeatServiceProvider }: FirebaseInstallationsImpl,\n { fid }: InProgressInstallationEntry\n): Promise {\n const endpoint = getInstallationsEndpoint(appConfig);\n\n const headers = getHeaders(appConfig);\n\n // If heartbeat service exists, add the heartbeat string to the header.\n const heartbeatService = heartbeatServiceProvider.getImmediate({\n optional: true\n });\n if (heartbeatService) {\n const heartbeatsHeader = await heartbeatService.getHeartbeatsHeader();\n if (heartbeatsHeader) {\n headers.append('x-firebase-client', heartbeatsHeader);\n }\n }\n\n const body = {\n fid,\n authVersion: INTERNAL_AUTH_VERSION,\n appId: appConfig.appId,\n sdkVersion: PACKAGE_VERSION\n };\n\n const request: RequestInit = {\n method: 'POST',\n headers,\n body: JSON.stringify(body)\n };\n\n const response = await retryIfServerError(() => fetch(endpoint, request));\n if (response.ok) {\n const responseValue: CreateInstallationResponse = await response.json();\n const registeredInstallationEntry: RegisteredInstallationEntry = {\n fid: responseValue.fid || fid,\n registrationStatus: RequestStatus.COMPLETED,\n refreshToken: responseValue.refreshToken,\n authToken: extractAuthTokenInfoFromResponse(responseValue.authToken)\n };\n return registeredInstallationEntry;\n } else {\n throw await getErrorFromResponse('Create Installation', response);\n }\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/** Returns a promise that resolves after given time passes. */\nexport function sleep(ms: number): Promise {\n return new Promise(resolve => {\n setTimeout(resolve, ms);\n });\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport function bufferToBase64UrlSafe(array: Uint8Array): string {\n const b64 = btoa(String.fromCharCode(...array));\n return b64.replace(/\\+/g, '-').replace(/\\//g, '_');\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { bufferToBase64UrlSafe } from './buffer-to-base64-url-safe';\n\nexport const VALID_FID_PATTERN = /^[cdef][\\w-]{21}$/;\nexport const INVALID_FID = '';\n\n/**\n * Generates a new FID using random values from Web Crypto API.\n * Returns an empty string if FID generation fails for any reason.\n */\nexport function generateFid(): string {\n try {\n // A valid FID has exactly 22 base64 characters, which is 132 bits, or 16.5\n // bytes. our implementation generates a 17 byte array instead.\n const fidByteArray = new Uint8Array(17);\n const crypto =\n self.crypto || (self as unknown as { msCrypto: Crypto }).msCrypto;\n crypto.getRandomValues(fidByteArray);\n\n // Replace the first 4 random bits with the constant FID header of 0b0111.\n fidByteArray[0] = 0b01110000 + (fidByteArray[0] % 0b00010000);\n\n const fid = encode(fidByteArray);\n\n return VALID_FID_PATTERN.test(fid) ? fid : INVALID_FID;\n } catch {\n // FID generation errored\n return INVALID_FID;\n }\n}\n\n/** Converts a FID Uint8Array to a base64 string representation. */\nfunction encode(fidByteArray: Uint8Array): string {\n const b64String = bufferToBase64UrlSafe(fidByteArray);\n\n // Remove the 23rd character that was added because of the extra 4 bits at the\n // end of our 17 byte array, and the '=' padding.\n return b64String.substr(0, 22);\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { AppConfig } from '../interfaces/installation-impl';\n\n/** Returns a string key that can be used to identify the app. */\nexport function getKey(appConfig: AppConfig): string {\n return `${appConfig.appName}!${appConfig.appId}`;\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { getKey } from '../util/get-key';\nimport { AppConfig } from '../interfaces/installation-impl';\nimport { IdChangeCallbackFn } from '../api';\n\nconst fidChangeCallbacks: Map> = new Map();\n\n/**\n * Calls the onIdChange callbacks with the new FID value, and broadcasts the\n * change to other tabs.\n */\nexport function fidChanged(appConfig: AppConfig, fid: string): void {\n const key = getKey(appConfig);\n\n callFidChangeCallbacks(key, fid);\n broadcastFidChange(key, fid);\n}\n\nexport function addCallback(\n appConfig: AppConfig,\n callback: IdChangeCallbackFn\n): void {\n // Open the broadcast channel if it's not already open,\n // to be able to listen to change events from other tabs.\n getBroadcastChannel();\n\n const key = getKey(appConfig);\n\n let callbackSet = fidChangeCallbacks.get(key);\n if (!callbackSet) {\n callbackSet = new Set();\n fidChangeCallbacks.set(key, callbackSet);\n }\n callbackSet.add(callback);\n}\n\nexport function removeCallback(\n appConfig: AppConfig,\n callback: IdChangeCallbackFn\n): void {\n const key = getKey(appConfig);\n\n const callbackSet = fidChangeCallbacks.get(key);\n\n if (!callbackSet) {\n return;\n }\n\n callbackSet.delete(callback);\n if (callbackSet.size === 0) {\n fidChangeCallbacks.delete(key);\n }\n\n // Close broadcast channel if there are no more callbacks.\n closeBroadcastChannel();\n}\n\nfunction callFidChangeCallbacks(key: string, fid: string): void {\n const callbacks = fidChangeCallbacks.get(key);\n if (!callbacks) {\n return;\n }\n\n for (const callback of callbacks) {\n callback(fid);\n }\n}\n\nfunction broadcastFidChange(key: string, fid: string): void {\n const channel = getBroadcastChannel();\n if (channel) {\n channel.postMessage({ key, fid });\n }\n closeBroadcastChannel();\n}\n\nlet broadcastChannel: BroadcastChannel | null = null;\n/** Opens and returns a BroadcastChannel if it is supported by the browser. */\nfunction getBroadcastChannel(): BroadcastChannel | null {\n if (!broadcastChannel && 'BroadcastChannel' in self) {\n broadcastChannel = new BroadcastChannel('[Firebase] FID Change');\n broadcastChannel.onmessage = e => {\n callFidChangeCallbacks(e.data.key, e.data.fid);\n };\n }\n return broadcastChannel;\n}\n\nfunction closeBroadcastChannel(): void {\n if (fidChangeCallbacks.size === 0 && broadcastChannel) {\n broadcastChannel.close();\n broadcastChannel = null;\n }\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { DBSchema, IDBPDatabase, openDB } from 'idb';\nimport { AppConfig } from '../interfaces/installation-impl';\nimport { InstallationEntry } from '../interfaces/installation-entry';\nimport { getKey } from '../util/get-key';\nimport { fidChanged } from './fid-changed';\n\nconst DATABASE_NAME = 'firebase-installations-database';\nconst DATABASE_VERSION = 1;\nconst OBJECT_STORE_NAME = 'firebase-installations-store';\n\ninterface InstallationsDB extends DBSchema {\n 'firebase-installations-store': {\n key: string;\n value: InstallationEntry | undefined;\n };\n}\n\nlet dbPromise: Promise> | null = null;\nfunction getDbPromise(): Promise> {\n if (!dbPromise) {\n dbPromise = openDB(DATABASE_NAME, DATABASE_VERSION, {\n upgrade: (db, oldVersion) => {\n // We don't use 'break' in this switch statement, the fall-through\n // behavior is what we want, because if there are multiple versions between\n // the old version and the current version, we want ALL the migrations\n // that correspond to those versions to run, not only the last one.\n // eslint-disable-next-line default-case\n switch (oldVersion) {\n case 0:\n db.createObjectStore(OBJECT_STORE_NAME);\n }\n }\n });\n }\n return dbPromise;\n}\n\n/** Gets record(s) from the objectStore that match the given key. */\nexport async function get(\n appConfig: AppConfig\n): Promise {\n const key = getKey(appConfig);\n const db = await getDbPromise();\n return db\n .transaction(OBJECT_STORE_NAME)\n .objectStore(OBJECT_STORE_NAME)\n .get(key) as Promise;\n}\n\n/** Assigns or overwrites the record for the given key with the given value. */\nexport async function set(\n appConfig: AppConfig,\n value: ValueType\n): Promise {\n const key = getKey(appConfig);\n const db = await getDbPromise();\n const tx = db.transaction(OBJECT_STORE_NAME, 'readwrite');\n const objectStore = tx.objectStore(OBJECT_STORE_NAME);\n const oldValue = (await objectStore.get(key)) as InstallationEntry;\n await objectStore.put(value, key);\n await tx.done;\n\n if (!oldValue || oldValue.fid !== value.fid) {\n fidChanged(appConfig, value.fid);\n }\n\n return value;\n}\n\n/** Removes record(s) from the objectStore that match the given key. */\nexport async function remove(appConfig: AppConfig): Promise {\n const key = getKey(appConfig);\n const db = await getDbPromise();\n const tx = db.transaction(OBJECT_STORE_NAME, 'readwrite');\n await tx.objectStore(OBJECT_STORE_NAME).delete(key);\n await tx.done;\n}\n\n/**\n * Atomically updates a record with the result of updateFn, which gets\n * called with the current value. If newValue is undefined, the record is\n * deleted instead.\n * @return Updated value\n */\nexport async function update(\n appConfig: AppConfig,\n updateFn: (previousValue: InstallationEntry | undefined) => ValueType\n): Promise {\n const key = getKey(appConfig);\n const db = await getDbPromise();\n const tx = db.transaction(OBJECT_STORE_NAME, 'readwrite');\n const store = tx.objectStore(OBJECT_STORE_NAME);\n const oldValue: InstallationEntry | undefined = (await store.get(\n key\n )) as InstallationEntry;\n const newValue = updateFn(oldValue);\n\n if (newValue === undefined) {\n await store.delete(key);\n } else {\n await store.put(newValue, key);\n }\n await tx.done;\n\n if (newValue && (!oldValue || oldValue.fid !== newValue.fid)) {\n fidChanged(appConfig, newValue.fid);\n }\n\n return newValue;\n}\n\nexport async function clear(): Promise {\n const db = await getDbPromise();\n const tx = db.transaction(OBJECT_STORE_NAME, 'readwrite');\n await tx.objectStore(OBJECT_STORE_NAME).clear();\n await tx.done;\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { createInstallationRequest } from '../functions/create-installation-request';\nimport {\n AppConfig,\n FirebaseInstallationsImpl\n} from '../interfaces/installation-impl';\nimport {\n InProgressInstallationEntry,\n InstallationEntry,\n RegisteredInstallationEntry,\n RequestStatus\n} from '../interfaces/installation-entry';\nimport { PENDING_TIMEOUT_MS } from '../util/constants';\nimport { ERROR_FACTORY, ErrorCode, isServerError } from '../util/errors';\nimport { sleep } from '../util/sleep';\nimport { generateFid, INVALID_FID } from './generate-fid';\nimport { remove, set, update } from './idb-manager';\n\nexport interface InstallationEntryWithRegistrationPromise {\n installationEntry: InstallationEntry;\n /** Exist iff the installationEntry is not registered. */\n registrationPromise?: Promise;\n}\n\n/**\n * Updates and returns the InstallationEntry from the database.\n * Also triggers a registration request if it is necessary and possible.\n */\nexport async function getInstallationEntry(\n installations: FirebaseInstallationsImpl\n): Promise {\n let registrationPromise: Promise | undefined;\n\n const installationEntry = await update(installations.appConfig, oldEntry => {\n const installationEntry = updateOrCreateInstallationEntry(oldEntry);\n const entryWithPromise = triggerRegistrationIfNecessary(\n installations,\n installationEntry\n );\n registrationPromise = entryWithPromise.registrationPromise;\n return entryWithPromise.installationEntry;\n });\n\n if (installationEntry.fid === INVALID_FID) {\n // FID generation failed. Waiting for the FID from the server.\n return { installationEntry: await registrationPromise! };\n }\n\n return {\n installationEntry,\n registrationPromise\n };\n}\n\n/**\n * Creates a new Installation Entry if one does not exist.\n * Also clears timed out pending requests.\n */\nfunction updateOrCreateInstallationEntry(\n oldEntry: InstallationEntry | undefined\n): InstallationEntry {\n const entry: InstallationEntry = oldEntry || {\n fid: generateFid(),\n registrationStatus: RequestStatus.NOT_STARTED\n };\n\n return clearTimedOutRequest(entry);\n}\n\n/**\n * If the Firebase Installation is not registered yet, this will trigger the\n * registration and return an InProgressInstallationEntry.\n *\n * If registrationPromise does not exist, the installationEntry is guaranteed\n * to be registered.\n */\nfunction triggerRegistrationIfNecessary(\n installations: FirebaseInstallationsImpl,\n installationEntry: InstallationEntry\n): InstallationEntryWithRegistrationPromise {\n if (installationEntry.registrationStatus === RequestStatus.NOT_STARTED) {\n if (!navigator.onLine) {\n // Registration required but app is offline.\n const registrationPromiseWithError = Promise.reject(\n ERROR_FACTORY.create(ErrorCode.APP_OFFLINE)\n );\n return {\n installationEntry,\n registrationPromise: registrationPromiseWithError\n };\n }\n\n // Try registering. Change status to IN_PROGRESS.\n const inProgressEntry: InProgressInstallationEntry = {\n fid: installationEntry.fid,\n registrationStatus: RequestStatus.IN_PROGRESS,\n registrationTime: Date.now()\n };\n const registrationPromise = registerInstallation(\n installations,\n inProgressEntry\n );\n return { installationEntry: inProgressEntry, registrationPromise };\n } else if (\n installationEntry.registrationStatus === RequestStatus.IN_PROGRESS\n ) {\n return {\n installationEntry,\n registrationPromise: waitUntilFidRegistration(installations)\n };\n } else {\n return { installationEntry };\n }\n}\n\n/** This will be executed only once for each new Firebase Installation. */\nasync function registerInstallation(\n installations: FirebaseInstallationsImpl,\n installationEntry: InProgressInstallationEntry\n): Promise {\n try {\n const registeredInstallationEntry = await createInstallationRequest(\n installations,\n installationEntry\n );\n return set(installations.appConfig, registeredInstallationEntry);\n } catch (e) {\n if (isServerError(e) && e.customData.serverCode === 409) {\n // Server returned a \"FID can not be used\" error.\n // Generate a new ID next time.\n await remove(installations.appConfig);\n } else {\n // Registration failed. Set FID as not registered.\n await set(installations.appConfig, {\n fid: installationEntry.fid,\n registrationStatus: RequestStatus.NOT_STARTED\n });\n }\n throw e;\n }\n}\n\n/** Call if FID registration is pending in another request. */\nasync function waitUntilFidRegistration(\n installations: FirebaseInstallationsImpl\n): Promise {\n // Unfortunately, there is no way of reliably observing when a value in\n // IndexedDB changes (yet, see https://github.com/WICG/indexed-db-observers),\n // so we need to poll.\n\n let entry: InstallationEntry = await updateInstallationRequest(\n installations.appConfig\n );\n while (entry.registrationStatus === RequestStatus.IN_PROGRESS) {\n // createInstallation request still in progress.\n await sleep(100);\n\n entry = await updateInstallationRequest(installations.appConfig);\n }\n\n if (entry.registrationStatus === RequestStatus.NOT_STARTED) {\n // The request timed out or failed in a different call. Try again.\n const { installationEntry, registrationPromise } =\n await getInstallationEntry(installations);\n\n if (registrationPromise) {\n return registrationPromise;\n } else {\n // if there is no registrationPromise, entry is registered.\n return installationEntry as RegisteredInstallationEntry;\n }\n }\n\n return entry;\n}\n\n/**\n * Called only if there is a CreateInstallation request in progress.\n *\n * Updates the InstallationEntry in the DB based on the status of the\n * CreateInstallation request.\n *\n * Returns the updated InstallationEntry.\n */\nfunction updateInstallationRequest(\n appConfig: AppConfig\n): Promise {\n return update(appConfig, oldEntry => {\n if (!oldEntry) {\n throw ERROR_FACTORY.create(ErrorCode.INSTALLATION_NOT_FOUND);\n }\n return clearTimedOutRequest(oldEntry);\n });\n}\n\nfunction clearTimedOutRequest(entry: InstallationEntry): InstallationEntry {\n if (hasInstallationRequestTimedOut(entry)) {\n return {\n fid: entry.fid,\n registrationStatus: RequestStatus.NOT_STARTED\n };\n }\n\n return entry;\n}\n\nfunction hasInstallationRequestTimedOut(\n installationEntry: InstallationEntry\n): boolean {\n return (\n installationEntry.registrationStatus === RequestStatus.IN_PROGRESS &&\n installationEntry.registrationTime + PENDING_TIMEOUT_MS < Date.now()\n );\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { GenerateAuthTokenResponse } from '../interfaces/api-response';\nimport {\n CompletedAuthToken,\n RegisteredInstallationEntry\n} from '../interfaces/installation-entry';\nimport { PACKAGE_VERSION } from '../util/constants';\nimport {\n extractAuthTokenInfoFromResponse,\n getErrorFromResponse,\n getHeadersWithAuth,\n getInstallationsEndpoint,\n retryIfServerError\n} from './common';\nimport {\n FirebaseInstallationsImpl,\n AppConfig\n} from '../interfaces/installation-impl';\n\nexport async function generateAuthTokenRequest(\n { appConfig, heartbeatServiceProvider }: FirebaseInstallationsImpl,\n installationEntry: RegisteredInstallationEntry\n): Promise {\n const endpoint = getGenerateAuthTokenEndpoint(appConfig, installationEntry);\n\n const headers = getHeadersWithAuth(appConfig, installationEntry);\n\n // If heartbeat service exists, add the heartbeat string to the header.\n const heartbeatService = heartbeatServiceProvider.getImmediate({\n optional: true\n });\n if (heartbeatService) {\n const heartbeatsHeader = await heartbeatService.getHeartbeatsHeader();\n if (heartbeatsHeader) {\n headers.append('x-firebase-client', heartbeatsHeader);\n }\n }\n\n const body = {\n installation: {\n sdkVersion: PACKAGE_VERSION,\n appId: appConfig.appId\n }\n };\n\n const request: RequestInit = {\n method: 'POST',\n headers,\n body: JSON.stringify(body)\n };\n\n const response = await retryIfServerError(() => fetch(endpoint, request));\n if (response.ok) {\n const responseValue: GenerateAuthTokenResponse = await response.json();\n const completedAuthToken: CompletedAuthToken =\n extractAuthTokenInfoFromResponse(responseValue);\n return completedAuthToken;\n } else {\n throw await getErrorFromResponse('Generate Auth Token', response);\n }\n}\n\nfunction getGenerateAuthTokenEndpoint(\n appConfig: AppConfig,\n { fid }: RegisteredInstallationEntry\n): string {\n return `${getInstallationsEndpoint(appConfig)}/${fid}/authTokens:generate`;\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { generateAuthTokenRequest } from '../functions/generate-auth-token-request';\nimport {\n AppConfig,\n FirebaseInstallationsImpl\n} from '../interfaces/installation-impl';\nimport {\n AuthToken,\n CompletedAuthToken,\n InProgressAuthToken,\n InstallationEntry,\n RegisteredInstallationEntry,\n RequestStatus\n} from '../interfaces/installation-entry';\nimport { PENDING_TIMEOUT_MS, TOKEN_EXPIRATION_BUFFER } from '../util/constants';\nimport { ERROR_FACTORY, ErrorCode, isServerError } from '../util/errors';\nimport { sleep } from '../util/sleep';\nimport { remove, set, update } from './idb-manager';\n\n/**\n * Returns a valid authentication token for the installation. Generates a new\n * token if one doesn't exist, is expired or about to expire.\n *\n * Should only be called if the Firebase Installation is registered.\n */\nexport async function refreshAuthToken(\n installations: FirebaseInstallationsImpl,\n forceRefresh = false\n): Promise {\n let tokenPromise: Promise | undefined;\n const entry = await update(installations.appConfig, oldEntry => {\n if (!isEntryRegistered(oldEntry)) {\n throw ERROR_FACTORY.create(ErrorCode.NOT_REGISTERED);\n }\n\n const oldAuthToken = oldEntry.authToken;\n if (!forceRefresh && isAuthTokenValid(oldAuthToken)) {\n // There is a valid token in the DB.\n return oldEntry;\n } else if (oldAuthToken.requestStatus === RequestStatus.IN_PROGRESS) {\n // There already is a token request in progress.\n tokenPromise = waitUntilAuthTokenRequest(installations, forceRefresh);\n return oldEntry;\n } else {\n // No token or token expired.\n if (!navigator.onLine) {\n throw ERROR_FACTORY.create(ErrorCode.APP_OFFLINE);\n }\n\n const inProgressEntry = makeAuthTokenRequestInProgressEntry(oldEntry);\n tokenPromise = fetchAuthTokenFromServer(installations, inProgressEntry);\n return inProgressEntry;\n }\n });\n\n const authToken = tokenPromise\n ? await tokenPromise\n : (entry.authToken as CompletedAuthToken);\n return authToken;\n}\n\n/**\n * Call only if FID is registered and Auth Token request is in progress.\n *\n * Waits until the current pending request finishes. If the request times out,\n * tries once in this thread as well.\n */\nasync function waitUntilAuthTokenRequest(\n installations: FirebaseInstallationsImpl,\n forceRefresh: boolean\n): Promise {\n // Unfortunately, there is no way of reliably observing when a value in\n // IndexedDB changes (yet, see https://github.com/WICG/indexed-db-observers),\n // so we need to poll.\n\n let entry = await updateAuthTokenRequest(installations.appConfig);\n while (entry.authToken.requestStatus === RequestStatus.IN_PROGRESS) {\n // generateAuthToken still in progress.\n await sleep(100);\n\n entry = await updateAuthTokenRequest(installations.appConfig);\n }\n\n const authToken = entry.authToken;\n if (authToken.requestStatus === RequestStatus.NOT_STARTED) {\n // The request timed out or failed in a different call. Try again.\n return refreshAuthToken(installations, forceRefresh);\n } else {\n return authToken;\n }\n}\n\n/**\n * Called only if there is a GenerateAuthToken request in progress.\n *\n * Updates the InstallationEntry in the DB based on the status of the\n * GenerateAuthToken request.\n *\n * Returns the updated InstallationEntry.\n */\nfunction updateAuthTokenRequest(\n appConfig: AppConfig\n): Promise {\n return update(appConfig, oldEntry => {\n if (!isEntryRegistered(oldEntry)) {\n throw ERROR_FACTORY.create(ErrorCode.NOT_REGISTERED);\n }\n\n const oldAuthToken = oldEntry.authToken;\n if (hasAuthTokenRequestTimedOut(oldAuthToken)) {\n return {\n ...oldEntry,\n authToken: { requestStatus: RequestStatus.NOT_STARTED }\n };\n }\n\n return oldEntry;\n });\n}\n\nasync function fetchAuthTokenFromServer(\n installations: FirebaseInstallationsImpl,\n installationEntry: RegisteredInstallationEntry\n): Promise {\n try {\n const authToken = await generateAuthTokenRequest(\n installations,\n installationEntry\n );\n const updatedInstallationEntry: RegisteredInstallationEntry = {\n ...installationEntry,\n authToken\n };\n await set(installations.appConfig, updatedInstallationEntry);\n return authToken;\n } catch (e) {\n if (\n isServerError(e) &&\n (e.customData.serverCode === 401 || e.customData.serverCode === 404)\n ) {\n // Server returned a \"FID not found\" or a \"Invalid authentication\" error.\n // Generate a new ID next time.\n await remove(installations.appConfig);\n } else {\n const updatedInstallationEntry: RegisteredInstallationEntry = {\n ...installationEntry,\n authToken: { requestStatus: RequestStatus.NOT_STARTED }\n };\n await set(installations.appConfig, updatedInstallationEntry);\n }\n throw e;\n }\n}\n\nfunction isEntryRegistered(\n installationEntry: InstallationEntry | undefined\n): installationEntry is RegisteredInstallationEntry {\n return (\n installationEntry !== undefined &&\n installationEntry.registrationStatus === RequestStatus.COMPLETED\n );\n}\n\nfunction isAuthTokenValid(authToken: AuthToken): boolean {\n return (\n authToken.requestStatus === RequestStatus.COMPLETED &&\n !isAuthTokenExpired(authToken)\n );\n}\n\nfunction isAuthTokenExpired(authToken: CompletedAuthToken): boolean {\n const now = Date.now();\n return (\n now < authToken.creationTime ||\n authToken.creationTime + authToken.expiresIn < now + TOKEN_EXPIRATION_BUFFER\n );\n}\n\n/** Returns an updated InstallationEntry with an InProgressAuthToken. */\nfunction makeAuthTokenRequestInProgressEntry(\n oldEntry: RegisteredInstallationEntry\n): RegisteredInstallationEntry {\n const inProgressAuthToken: InProgressAuthToken = {\n requestStatus: RequestStatus.IN_PROGRESS,\n requestTime: Date.now()\n };\n return {\n ...oldEntry,\n authToken: inProgressAuthToken\n };\n}\n\nfunction hasAuthTokenRequestTimedOut(authToken: AuthToken): boolean {\n return (\n authToken.requestStatus === RequestStatus.IN_PROGRESS &&\n authToken.requestTime + PENDING_TIMEOUT_MS < Date.now()\n );\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { getInstallationEntry } from '../helpers/get-installation-entry';\nimport { refreshAuthToken } from '../helpers/refresh-auth-token';\nimport { FirebaseInstallationsImpl } from '../interfaces/installation-impl';\nimport { Installations } from '../interfaces/public-types';\n\n/**\n * Creates a Firebase Installation if there isn't one for the app and\n * returns the Installation ID.\n * @param installations - The `Installations` instance.\n *\n * @public\n */\nexport async function getId(installations: Installations): Promise {\n const installationsImpl = installations as FirebaseInstallationsImpl;\n const { installationEntry, registrationPromise } = await getInstallationEntry(\n installationsImpl\n );\n\n if (registrationPromise) {\n registrationPromise.catch(console.error);\n } else {\n // If the installation is already registered, update the authentication\n // token if needed.\n refreshAuthToken(installationsImpl).catch(console.error);\n }\n\n return installationEntry.fid;\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { getInstallationEntry } from '../helpers/get-installation-entry';\nimport { refreshAuthToken } from '../helpers/refresh-auth-token';\nimport { FirebaseInstallationsImpl } from '../interfaces/installation-impl';\nimport { Installations } from '../interfaces/public-types';\n\n/**\n * Returns a Firebase Installations auth token, identifying the current\n * Firebase Installation.\n * @param installations - The `Installations` instance.\n * @param forceRefresh - Force refresh regardless of token expiration.\n *\n * @public\n */\nexport async function getToken(\n installations: Installations,\n forceRefresh = false\n): Promise {\n const installationsImpl = installations as FirebaseInstallationsImpl;\n await completeInstallationRegistration(installationsImpl);\n\n // At this point we either have a Registered Installation in the DB, or we've\n // already thrown an error.\n const authToken = await refreshAuthToken(installationsImpl, forceRefresh);\n return authToken.token;\n}\n\nasync function completeInstallationRegistration(\n installations: FirebaseInstallationsImpl\n): Promise {\n const { registrationPromise } = await getInstallationEntry(installations);\n\n if (registrationPromise) {\n // A createInstallation request is in progress. Wait until it finishes.\n await registrationPromise;\n }\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { AppConfig } from '../interfaces/installation-impl';\nimport { RegisteredInstallationEntry } from '../interfaces/installation-entry';\nimport {\n getErrorFromResponse,\n getHeadersWithAuth,\n getInstallationsEndpoint,\n retryIfServerError\n} from './common';\n\nexport async function deleteInstallationRequest(\n appConfig: AppConfig,\n installationEntry: RegisteredInstallationEntry\n): Promise {\n const endpoint = getDeleteEndpoint(appConfig, installationEntry);\n\n const headers = getHeadersWithAuth(appConfig, installationEntry);\n const request: RequestInit = {\n method: 'DELETE',\n headers\n };\n\n const response = await retryIfServerError(() => fetch(endpoint, request));\n if (!response.ok) {\n throw await getErrorFromResponse('Delete Installation', response);\n }\n}\n\nfunction getDeleteEndpoint(\n appConfig: AppConfig,\n { fid }: RegisteredInstallationEntry\n): string {\n return `${getInstallationsEndpoint(appConfig)}/${fid}`;\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { deleteInstallationRequest } from '../functions/delete-installation-request';\nimport { remove, update } from '../helpers/idb-manager';\nimport { RequestStatus } from '../interfaces/installation-entry';\nimport { ERROR_FACTORY, ErrorCode } from '../util/errors';\nimport { FirebaseInstallationsImpl } from '../interfaces/installation-impl';\nimport { Installations } from '../interfaces/public-types';\n\n/**\n * Deletes the Firebase Installation and all associated data.\n * @param installations - The `Installations` instance.\n *\n * @public\n */\nexport async function deleteInstallations(\n installations: Installations\n): Promise {\n const { appConfig } = installations as FirebaseInstallationsImpl;\n\n const entry = await update(appConfig, oldEntry => {\n if (oldEntry && oldEntry.registrationStatus === RequestStatus.NOT_STARTED) {\n // Delete the unregistered entry without sending a deleteInstallation request.\n return undefined;\n }\n return oldEntry;\n });\n\n if (entry) {\n if (entry.registrationStatus === RequestStatus.IN_PROGRESS) {\n // Can't delete while trying to register.\n throw ERROR_FACTORY.create(ErrorCode.DELETE_PENDING_REGISTRATION);\n } else if (entry.registrationStatus === RequestStatus.COMPLETED) {\n if (!navigator.onLine) {\n throw ERROR_FACTORY.create(ErrorCode.APP_OFFLINE);\n } else {\n await deleteInstallationRequest(appConfig, entry);\n await remove(appConfig);\n }\n }\n }\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { addCallback, removeCallback } from '../helpers/fid-changed';\nimport { FirebaseInstallationsImpl } from '../interfaces/installation-impl';\nimport { Installations } from '../interfaces/public-types';\n\n/**\n * An user defined callback function that gets called when Installations ID changes.\n *\n * @public\n */\nexport type IdChangeCallbackFn = (installationId: string) => void;\n/**\n * Unsubscribe a callback function previously added via {@link IdChangeCallbackFn}.\n *\n * @public\n */\nexport type IdChangeUnsubscribeFn = () => void;\n\n/**\n * Sets a new callback that will get called when Installation ID changes.\n * Returns an unsubscribe function that will remove the callback when called.\n * @param installations - The `Installations` instance.\n * @param callback - The callback function that is invoked when FID changes.\n * @returns A function that can be called to unsubscribe.\n *\n * @public\n */\nexport function onIdChange(\n installations: Installations,\n callback: IdChangeCallbackFn\n): IdChangeUnsubscribeFn {\n const { appConfig } = installations as FirebaseInstallationsImpl;\n\n addCallback(appConfig, callback);\n return () => {\n removeCallback(appConfig, callback);\n };\n}\n", "/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { FirebaseApp, getApp, _getProvider } from '@firebase/app';\nimport { Installations } from '../interfaces/public-types';\n\n/**\n * Returns an instance of {@link Installations} associated with the given\n * {@link @firebase/app#FirebaseApp} instance.\n * @param app - The {@link @firebase/app#FirebaseApp} instance.\n *\n * @public\n */\nexport function getInstallations(app: FirebaseApp = getApp()): Installations {\n const installationsImpl = _getProvider(app, 'installations').getImmediate();\n return installationsImpl;\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { FirebaseApp, FirebaseOptions } from '@firebase/app';\nimport { FirebaseError } from '@firebase/util';\nimport { AppConfig } from '../interfaces/installation-impl';\nimport { ERROR_FACTORY, ErrorCode } from '../util/errors';\n\nexport function extractAppConfig(app: FirebaseApp): AppConfig {\n if (!app || !app.options) {\n throw getMissingValueError('App Configuration');\n }\n\n if (!app.name) {\n throw getMissingValueError('App Name');\n }\n\n // Required app config keys\n const configKeys: Array = [\n 'projectId',\n 'apiKey',\n 'appId'\n ];\n\n for (const keyName of configKeys) {\n if (!app.options[keyName]) {\n throw getMissingValueError(keyName);\n }\n }\n\n return {\n appName: app.name,\n projectId: app.options.projectId!,\n apiKey: app.options.apiKey!,\n appId: app.options.appId!\n };\n}\n\nfunction getMissingValueError(valueName: string): FirebaseError {\n return ERROR_FACTORY.create(ErrorCode.MISSING_APP_CONFIG_VALUES, {\n valueName\n });\n}\n", "/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { _registerComponent, _getProvider } from '@firebase/app';\nimport {\n Component,\n ComponentType,\n InstanceFactory,\n ComponentContainer\n} from '@firebase/component';\nimport { getId, getToken } from '../api/index';\nimport { _FirebaseInstallationsInternal } from '../interfaces/public-types';\nimport { FirebaseInstallationsImpl } from '../interfaces/installation-impl';\nimport { extractAppConfig } from '../helpers/extract-app-config';\n\nconst INSTALLATIONS_NAME = 'installations';\nconst INSTALLATIONS_NAME_INTERNAL = 'installations-internal';\n\nconst publicFactory: InstanceFactory<'installations'> = (\n container: ComponentContainer\n) => {\n const app = container.getProvider('app').getImmediate();\n // Throws if app isn't configured properly.\n const appConfig = extractAppConfig(app);\n const heartbeatServiceProvider = _getProvider(app, 'heartbeat');\n\n const installationsImpl: FirebaseInstallationsImpl = {\n app,\n appConfig,\n heartbeatServiceProvider,\n _delete: () => Promise.resolve()\n };\n return installationsImpl;\n};\n\nconst internalFactory: InstanceFactory<'installations-internal'> = (\n container: ComponentContainer\n) => {\n const app = container.getProvider('app').getImmediate();\n // Internal FIS instance relies on public FIS instance.\n const installations = _getProvider(app, INSTALLATIONS_NAME).getImmediate();\n\n const installationsInternal: _FirebaseInstallationsInternal = {\n getId: () => getId(installations),\n getToken: (forceRefresh?: boolean) => getToken(installations, forceRefresh)\n };\n return installationsInternal;\n};\n\nexport function registerInstallations(): void {\n _registerComponent(\n new Component(INSTALLATIONS_NAME, publicFactory, ComponentType.PUBLIC)\n );\n _registerComponent(\n new Component(\n INSTALLATIONS_NAME_INTERNAL,\n internalFactory,\n ComponentType.PRIVATE\n )\n );\n}\n", "/**\n * Firebase Installations\n *\n * @packageDocumentation\n */\n\n/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { registerInstallations } from './functions/config';\nimport { registerVersion } from '@firebase/app';\nimport { name, version } from '../package.json';\n\nexport * from './api';\nexport * from './interfaces/public-types';\n\nregisterInstallations();\nregisterVersion(name, version);\n// BUILD_TARGET will be replaced by values like esm5, esm2017, cjs5, etc during the compilation\nregisterVersion(name, version, '__BUILD_TARGET__');\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport const DEFAULT_SW_PATH = '/firebase-messaging-sw.js';\nexport const DEFAULT_SW_SCOPE = '/firebase-cloud-messaging-push-scope';\n\nexport const DEFAULT_VAPID_KEY =\n 'BDOU99-h67HcA6JeFXHbSNMu7e2yNNu3RzoMj8TM4W88jITfq7ZmPvIM1Iv-4_l2LxQcYwhqby2xGpWwzjfAnG4';\n\nexport const ENDPOINT = 'https://fcmregistrations.googleapis.com/v1';\n\n/** Key of FCM Payload in Notification's data field. */\nexport const FCM_MSG = 'FCM_MSG';\n\nexport const CONSOLE_CAMPAIGN_ID = 'google.c.a.c_id';\nexport const CONSOLE_CAMPAIGN_NAME = 'google.c.a.c_l';\nexport const CONSOLE_CAMPAIGN_TIME = 'google.c.a.ts';\n/** Set to '1' if Analytics is enabled for the campaign */\nexport const CONSOLE_CAMPAIGN_ANALYTICS_ENABLED = 'google.c.a.e';\nexport const TAG = 'FirebaseMessaging: ';\nexport const MAX_NUMBER_OF_EVENTS_PER_LOG_REQUEST = 1000;\nexport const MAX_RETRIES = 3;\nexport const LOG_INTERVAL_IN_MS = 86400000; //24 hour\nexport const DEFAULT_BACKOFF_TIME_MS = 5000;\n\n// FCM log source name registered at Firelog: 'FCM_CLIENT_EVENT_LOGGING'. It uniquely identifies\n// FCM's logging configuration.\nexport const FCM_LOG_SOURCE = 1249;\n\n// Defined as in proto/messaging_event.proto. Neglecting fields that are supported.\nexport const SDK_PLATFORM_WEB = 3;\nexport const EVENT_MESSAGE_DELIVERED = 1;\n\nexport enum MessageType {\n DATA_MESSAGE = 1,\n DISPLAY_NOTIFICATION = 3\n}\n", "/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License. You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under the License\n * is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n * or implied. See the License for the specific language governing permissions and limitations under\n * the License.\n */\n\nimport {\n CONSOLE_CAMPAIGN_ANALYTICS_ENABLED,\n CONSOLE_CAMPAIGN_ID,\n CONSOLE_CAMPAIGN_NAME,\n CONSOLE_CAMPAIGN_TIME\n} from '../util/constants';\n\nexport interface MessagePayloadInternal {\n notification?: NotificationPayloadInternal;\n data?: unknown;\n fcmOptions?: FcmOptionsInternal;\n messageType?: MessageType;\n isFirebaseMessaging?: boolean;\n from: string;\n fcmMessageId: string;\n // eslint-disable-next-line camelcase\n collapse_key: string;\n}\n\nexport interface NotificationPayloadInternal extends NotificationOptions {\n title: string;\n // Supported in the Legacy Send API.\n // See:https://firebase.google.com/docs/cloud-messaging/xmpp-server-ref.\n // eslint-disable-next-line camelcase\n click_action?: string;\n}\n\n// Defined in\n// https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages#webpushfcmoptions. Note\n// that the keys are sent to the clients in snake cases which we need to convert to camel so it can\n// be exposed as a type to match the Firebase API convention.\nexport interface FcmOptionsInternal {\n link?: string;\n\n // eslint-disable-next-line camelcase\n analytics_label?: string;\n}\n\nexport enum MessageType {\n PUSH_RECEIVED = 'push-received',\n NOTIFICATION_CLICKED = 'notification-clicked'\n}\n\n/** Additional data of a message sent from the FN Console. */\nexport interface ConsoleMessageData {\n [CONSOLE_CAMPAIGN_ID]: string;\n [CONSOLE_CAMPAIGN_TIME]: string;\n [CONSOLE_CAMPAIGN_NAME]?: string;\n [CONSOLE_CAMPAIGN_ANALYTICS_ENABLED]?: '1';\n}\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport function arrayToBase64(array: Uint8Array | ArrayBuffer): string {\n const uint8Array = new Uint8Array(array);\n const base64String = btoa(String.fromCharCode(...uint8Array));\n return base64String.replace(/=/g, '').replace(/\\+/g, '-').replace(/\\//g, '_');\n}\n\nexport function base64ToArray(base64String: string): Uint8Array {\n const padding = '='.repeat((4 - (base64String.length % 4)) % 4);\n const base64 = (base64String + padding)\n .replace(/\\-/g, '+')\n .replace(/_/g, '/');\n\n const rawData = atob(base64);\n const outputArray = new Uint8Array(rawData.length);\n\n for (let i = 0; i < rawData.length; ++i) {\n outputArray[i] = rawData.charCodeAt(i);\n }\n return outputArray;\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { deleteDB, openDB } from 'idb';\n\nimport { TokenDetails } from '../interfaces/token-details';\nimport { arrayToBase64 } from './array-base64-translator';\n\n// https://github.com/firebase/firebase-js-sdk/blob/7857c212f944a2a9eb421fd4cb7370181bc034b5/packages/messaging/src/interfaces/token-details.ts\nexport interface V2TokenDetails {\n fcmToken: string;\n swScope: string;\n vapidKey: string | Uint8Array;\n subscription: PushSubscription;\n fcmSenderId: string;\n fcmPushSet: string;\n createTime?: number;\n endpoint?: string;\n auth?: string;\n p256dh?: string;\n}\n\n// https://github.com/firebase/firebase-js-sdk/blob/6b5b15ce4ea3df5df5df8a8b33a4e41e249c7715/packages/messaging/src/interfaces/token-details.ts\nexport interface V3TokenDetails {\n fcmToken: string;\n swScope: string;\n vapidKey: Uint8Array;\n fcmSenderId: string;\n fcmPushSet: string;\n endpoint: string;\n auth: ArrayBuffer;\n p256dh: ArrayBuffer;\n createTime: number;\n}\n\n// https://github.com/firebase/firebase-js-sdk/blob/9567dba664732f681fa7fe60f5b7032bb1daf4c9/packages/messaging/src/interfaces/token-details.ts\nexport interface V4TokenDetails {\n fcmToken: string;\n swScope: string;\n vapidKey: Uint8Array;\n fcmSenderId: string;\n endpoint: string;\n auth: ArrayBufferLike;\n p256dh: ArrayBufferLike;\n createTime: number;\n}\n\nconst OLD_DB_NAME = 'fcm_token_details_db';\n/**\n * The last DB version of 'fcm_token_details_db' was 4. This is one higher, so that the upgrade\n * callback is called for all versions of the old DB.\n */\nconst OLD_DB_VERSION = 5;\nconst OLD_OBJECT_STORE_NAME = 'fcm_token_object_Store';\n\nexport async function migrateOldDatabase(\n senderId: string\n): Promise {\n if ('databases' in indexedDB) {\n // indexedDb.databases() is an IndexedDB v3 API and does not exist in all browsers. TODO: Remove\n // typecast when it lands in TS types.\n const databases = await (\n indexedDB as {\n databases(): Promise>;\n }\n ).databases();\n const dbNames = databases.map(db => db.name);\n\n if (!dbNames.includes(OLD_DB_NAME)) {\n // old DB didn't exist, no need to open.\n return null;\n }\n }\n\n let tokenDetails: TokenDetails | null = null;\n\n const db = await openDB(OLD_DB_NAME, OLD_DB_VERSION, {\n upgrade: async (db, oldVersion, newVersion, upgradeTransaction) => {\n if (oldVersion < 2) {\n // Database too old, skip migration.\n return;\n }\n\n if (!db.objectStoreNames.contains(OLD_OBJECT_STORE_NAME)) {\n // Database did not exist. Nothing to do.\n return;\n }\n\n const objectStore = upgradeTransaction.objectStore(OLD_OBJECT_STORE_NAME);\n const value = await objectStore.index('fcmSenderId').get(senderId);\n await objectStore.clear();\n\n if (!value) {\n // No entry in the database, nothing to migrate.\n return;\n }\n\n if (oldVersion === 2) {\n const oldDetails = value as V2TokenDetails;\n\n if (!oldDetails.auth || !oldDetails.p256dh || !oldDetails.endpoint) {\n return;\n }\n\n tokenDetails = {\n token: oldDetails.fcmToken,\n createTime: oldDetails.createTime ?? Date.now(),\n subscriptionOptions: {\n auth: oldDetails.auth,\n p256dh: oldDetails.p256dh,\n endpoint: oldDetails.endpoint,\n swScope: oldDetails.swScope,\n vapidKey:\n typeof oldDetails.vapidKey === 'string'\n ? oldDetails.vapidKey\n : arrayToBase64(oldDetails.vapidKey)\n }\n };\n } else if (oldVersion === 3) {\n const oldDetails = value as V3TokenDetails;\n\n tokenDetails = {\n token: oldDetails.fcmToken,\n createTime: oldDetails.createTime,\n subscriptionOptions: {\n auth: arrayToBase64(oldDetails.auth),\n p256dh: arrayToBase64(oldDetails.p256dh),\n endpoint: oldDetails.endpoint,\n swScope: oldDetails.swScope,\n vapidKey: arrayToBase64(oldDetails.vapidKey)\n }\n };\n } else if (oldVersion === 4) {\n const oldDetails = value as V4TokenDetails;\n\n tokenDetails = {\n token: oldDetails.fcmToken,\n createTime: oldDetails.createTime,\n subscriptionOptions: {\n auth: arrayToBase64(oldDetails.auth),\n p256dh: arrayToBase64(oldDetails.p256dh),\n endpoint: oldDetails.endpoint,\n swScope: oldDetails.swScope,\n vapidKey: arrayToBase64(oldDetails.vapidKey)\n }\n };\n }\n }\n });\n db.close();\n\n // Delete all old databases.\n await deleteDB(OLD_DB_NAME);\n await deleteDB('fcm_vapid_details_db');\n await deleteDB('undefined');\n\n return checkTokenDetails(tokenDetails) ? tokenDetails : null;\n}\n\nfunction checkTokenDetails(\n tokenDetails: TokenDetails | null\n): tokenDetails is TokenDetails {\n if (!tokenDetails || !tokenDetails.subscriptionOptions) {\n return false;\n }\n const { subscriptionOptions } = tokenDetails;\n return (\n typeof tokenDetails.createTime === 'number' &&\n tokenDetails.createTime > 0 &&\n typeof tokenDetails.token === 'string' &&\n tokenDetails.token.length > 0 &&\n typeof subscriptionOptions.auth === 'string' &&\n subscriptionOptions.auth.length > 0 &&\n typeof subscriptionOptions.p256dh === 'string' &&\n subscriptionOptions.p256dh.length > 0 &&\n typeof subscriptionOptions.endpoint === 'string' &&\n subscriptionOptions.endpoint.length > 0 &&\n typeof subscriptionOptions.swScope === 'string' &&\n subscriptionOptions.swScope.length > 0 &&\n typeof subscriptionOptions.vapidKey === 'string' &&\n subscriptionOptions.vapidKey.length > 0\n );\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { DBSchema, IDBPDatabase, deleteDB, openDB } from 'idb';\n\nimport { FirebaseInternalDependencies } from '../interfaces/internal-dependencies';\nimport { TokenDetails } from '../interfaces/token-details';\nimport { migrateOldDatabase } from '../helpers/migrate-old-database';\n\n// Exported for tests.\nexport const DATABASE_NAME = 'firebase-messaging-database';\nconst DATABASE_VERSION = 1;\nconst OBJECT_STORE_NAME = 'firebase-messaging-store';\n\ninterface MessagingDB extends DBSchema {\n 'firebase-messaging-store': {\n key: string;\n value: TokenDetails;\n };\n}\n\nlet dbPromise: Promise> | null = null;\nfunction getDbPromise(): Promise> {\n if (!dbPromise) {\n dbPromise = openDB(DATABASE_NAME, DATABASE_VERSION, {\n upgrade: (upgradeDb, oldVersion) => {\n // We don't use 'break' in this switch statement, the fall-through behavior is what we want,\n // because if there are multiple versions between the old version and the current version, we\n // want ALL the migrations that correspond to those versions to run, not only the last one.\n // eslint-disable-next-line default-case\n switch (oldVersion) {\n case 0:\n upgradeDb.createObjectStore(OBJECT_STORE_NAME);\n }\n }\n });\n }\n return dbPromise;\n}\n\n/** Gets record(s) from the objectStore that match the given key. */\nexport async function dbGet(\n firebaseDependencies: FirebaseInternalDependencies\n): Promise {\n const key = getKey(firebaseDependencies);\n const db = await getDbPromise();\n const tokenDetails = (await db\n .transaction(OBJECT_STORE_NAME)\n .objectStore(OBJECT_STORE_NAME)\n .get(key)) as TokenDetails;\n\n if (tokenDetails) {\n return tokenDetails;\n } else {\n // Check if there is a tokenDetails object in the old DB.\n const oldTokenDetails = await migrateOldDatabase(\n firebaseDependencies.appConfig.senderId\n );\n if (oldTokenDetails) {\n await dbSet(firebaseDependencies, oldTokenDetails);\n return oldTokenDetails;\n }\n }\n}\n\n/** Assigns or overwrites the record for the given key with the given value. */\nexport async function dbSet(\n firebaseDependencies: FirebaseInternalDependencies,\n tokenDetails: TokenDetails\n): Promise {\n const key = getKey(firebaseDependencies);\n const db = await getDbPromise();\n const tx = db.transaction(OBJECT_STORE_NAME, 'readwrite');\n await tx.objectStore(OBJECT_STORE_NAME).put(tokenDetails, key);\n await tx.done;\n return tokenDetails;\n}\n\n/** Removes record(s) from the objectStore that match the given key. */\nexport async function dbRemove(\n firebaseDependencies: FirebaseInternalDependencies\n): Promise {\n const key = getKey(firebaseDependencies);\n const db = await getDbPromise();\n const tx = db.transaction(OBJECT_STORE_NAME, 'readwrite');\n await tx.objectStore(OBJECT_STORE_NAME).delete(key);\n await tx.done;\n}\n\n/** Deletes the DB. Useful for tests. */\nexport async function dbDelete(): Promise {\n if (dbPromise) {\n (await dbPromise).close();\n await deleteDB(DATABASE_NAME);\n dbPromise = null;\n }\n}\n\nfunction getKey({ appConfig }: FirebaseInternalDependencies): string {\n return appConfig.appId;\n}\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ErrorFactory, ErrorMap } from '@firebase/util';\n\nexport const enum ErrorCode {\n MISSING_APP_CONFIG_VALUES = 'missing-app-config-values',\n AVAILABLE_IN_WINDOW = 'only-available-in-window',\n AVAILABLE_IN_SW = 'only-available-in-sw',\n PERMISSION_DEFAULT = 'permission-default',\n PERMISSION_BLOCKED = 'permission-blocked',\n UNSUPPORTED_BROWSER = 'unsupported-browser',\n INDEXED_DB_UNSUPPORTED = 'indexed-db-unsupported',\n FAILED_DEFAULT_REGISTRATION = 'failed-service-worker-registration',\n TOKEN_SUBSCRIBE_FAILED = 'token-subscribe-failed',\n TOKEN_SUBSCRIBE_NO_TOKEN = 'token-subscribe-no-token',\n TOKEN_UNSUBSCRIBE_FAILED = 'token-unsubscribe-failed',\n TOKEN_UPDATE_FAILED = 'token-update-failed',\n TOKEN_UPDATE_NO_TOKEN = 'token-update-no-token',\n INVALID_BG_HANDLER = 'invalid-bg-handler',\n USE_SW_AFTER_GET_TOKEN = 'use-sw-after-get-token',\n INVALID_SW_REGISTRATION = 'invalid-sw-registration',\n USE_VAPID_KEY_AFTER_GET_TOKEN = 'use-vapid-key-after-get-token',\n INVALID_VAPID_KEY = 'invalid-vapid-key'\n}\n\nexport const ERROR_MAP: ErrorMap = {\n [ErrorCode.MISSING_APP_CONFIG_VALUES]:\n 'Missing App configuration value: \"{$valueName}\"',\n [ErrorCode.AVAILABLE_IN_WINDOW]:\n 'This method is available in a Window context.',\n [ErrorCode.AVAILABLE_IN_SW]:\n 'This method is available in a service worker context.',\n [ErrorCode.PERMISSION_DEFAULT]:\n 'The notification permission was not granted and dismissed instead.',\n [ErrorCode.PERMISSION_BLOCKED]:\n 'The notification permission was not granted and blocked instead.',\n [ErrorCode.UNSUPPORTED_BROWSER]:\n \"This browser doesn't support the API's required to use the Firebase SDK.\",\n [ErrorCode.INDEXED_DB_UNSUPPORTED]:\n \"This browser doesn't support indexedDb.open() (ex. Safari iFrame, Firefox Private Browsing, etc)\",\n [ErrorCode.FAILED_DEFAULT_REGISTRATION]:\n 'We are unable to register the default service worker. {$browserErrorMessage}',\n [ErrorCode.TOKEN_SUBSCRIBE_FAILED]:\n 'A problem occurred while subscribing the user to FCM: {$errorInfo}',\n [ErrorCode.TOKEN_SUBSCRIBE_NO_TOKEN]:\n 'FCM returned no token when subscribing the user to push.',\n [ErrorCode.TOKEN_UNSUBSCRIBE_FAILED]:\n 'A problem occurred while unsubscribing the ' +\n 'user from FCM: {$errorInfo}',\n [ErrorCode.TOKEN_UPDATE_FAILED]:\n 'A problem occurred while updating the user from FCM: {$errorInfo}',\n [ErrorCode.TOKEN_UPDATE_NO_TOKEN]:\n 'FCM returned no token when updating the user to push.',\n [ErrorCode.USE_SW_AFTER_GET_TOKEN]:\n 'The useServiceWorker() method may only be called once and must be ' +\n 'called before calling getToken() to ensure your service worker is used.',\n [ErrorCode.INVALID_SW_REGISTRATION]:\n 'The input to useServiceWorker() must be a ServiceWorkerRegistration.',\n [ErrorCode.INVALID_BG_HANDLER]:\n 'The input to setBackgroundMessageHandler() must be a function.',\n [ErrorCode.INVALID_VAPID_KEY]: 'The public VAPID key must be a string.',\n [ErrorCode.USE_VAPID_KEY_AFTER_GET_TOKEN]:\n 'The usePublicVapidKey() method may only be called once and must be ' +\n 'called before calling getToken() to ensure your VAPID key is used.'\n};\n\ninterface ErrorParams {\n [ErrorCode.MISSING_APP_CONFIG_VALUES]: {\n valueName: string;\n };\n [ErrorCode.FAILED_DEFAULT_REGISTRATION]: { browserErrorMessage: string };\n [ErrorCode.TOKEN_SUBSCRIBE_FAILED]: { errorInfo: string };\n [ErrorCode.TOKEN_UNSUBSCRIBE_FAILED]: { errorInfo: string };\n [ErrorCode.TOKEN_UPDATE_FAILED]: { errorInfo: string };\n}\n\nexport const ERROR_FACTORY = new ErrorFactory(\n 'messaging',\n 'Messaging',\n ERROR_MAP\n);\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { DEFAULT_VAPID_KEY, ENDPOINT } from '../util/constants';\nimport { ERROR_FACTORY, ErrorCode } from '../util/errors';\nimport { SubscriptionOptions, TokenDetails } from '../interfaces/token-details';\n\nimport { AppConfig } from '../interfaces/app-config';\nimport { FirebaseInternalDependencies } from '../interfaces/internal-dependencies';\n\nexport interface ApiResponse {\n token?: string;\n error?: { message: string };\n}\n\nexport interface ApiRequestBody {\n web: {\n endpoint: string;\n p256dh: string;\n auth: string;\n applicationPubKey?: string;\n };\n}\n\nexport async function requestGetToken(\n firebaseDependencies: FirebaseInternalDependencies,\n subscriptionOptions: SubscriptionOptions\n): Promise {\n const headers = await getHeaders(firebaseDependencies);\n const body = getBody(subscriptionOptions);\n\n const subscribeOptions = {\n method: 'POST',\n headers,\n body: JSON.stringify(body)\n };\n\n let responseData: ApiResponse;\n try {\n const response = await fetch(\n getEndpoint(firebaseDependencies.appConfig),\n subscribeOptions\n );\n responseData = await response.json();\n } catch (err) {\n throw ERROR_FACTORY.create(ErrorCode.TOKEN_SUBSCRIBE_FAILED, {\n errorInfo: (err as Error)?.toString()\n });\n }\n\n if (responseData.error) {\n const message = responseData.error.message;\n throw ERROR_FACTORY.create(ErrorCode.TOKEN_SUBSCRIBE_FAILED, {\n errorInfo: message\n });\n }\n\n if (!responseData.token) {\n throw ERROR_FACTORY.create(ErrorCode.TOKEN_SUBSCRIBE_NO_TOKEN);\n }\n\n return responseData.token;\n}\n\nexport async function requestUpdateToken(\n firebaseDependencies: FirebaseInternalDependencies,\n tokenDetails: TokenDetails\n): Promise {\n const headers = await getHeaders(firebaseDependencies);\n const body = getBody(tokenDetails.subscriptionOptions!);\n\n const updateOptions = {\n method: 'PATCH',\n headers,\n body: JSON.stringify(body)\n };\n\n let responseData: ApiResponse;\n try {\n const response = await fetch(\n `${getEndpoint(firebaseDependencies.appConfig)}/${tokenDetails.token}`,\n updateOptions\n );\n responseData = await response.json();\n } catch (err) {\n throw ERROR_FACTORY.create(ErrorCode.TOKEN_UPDATE_FAILED, {\n errorInfo: (err as Error)?.toString()\n });\n }\n\n if (responseData.error) {\n const message = responseData.error.message;\n throw ERROR_FACTORY.create(ErrorCode.TOKEN_UPDATE_FAILED, {\n errorInfo: message\n });\n }\n\n if (!responseData.token) {\n throw ERROR_FACTORY.create(ErrorCode.TOKEN_UPDATE_NO_TOKEN);\n }\n\n return responseData.token;\n}\n\nexport async function requestDeleteToken(\n firebaseDependencies: FirebaseInternalDependencies,\n token: string\n): Promise {\n const headers = await getHeaders(firebaseDependencies);\n\n const unsubscribeOptions = {\n method: 'DELETE',\n headers\n };\n\n try {\n const response = await fetch(\n `${getEndpoint(firebaseDependencies.appConfig)}/${token}`,\n unsubscribeOptions\n );\n const responseData: ApiResponse = await response.json();\n if (responseData.error) {\n const message = responseData.error.message;\n throw ERROR_FACTORY.create(ErrorCode.TOKEN_UNSUBSCRIBE_FAILED, {\n errorInfo: message\n });\n }\n } catch (err) {\n throw ERROR_FACTORY.create(ErrorCode.TOKEN_UNSUBSCRIBE_FAILED, {\n errorInfo: (err as Error)?.toString()\n });\n }\n}\n\nfunction getEndpoint({ projectId }: AppConfig): string {\n return `${ENDPOINT}/projects/${projectId!}/registrations`;\n}\n\nasync function getHeaders({\n appConfig,\n installations\n}: FirebaseInternalDependencies): Promise {\n const authToken = await installations.getToken();\n\n return new Headers({\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n 'x-goog-api-key': appConfig.apiKey!,\n 'x-goog-firebase-installations-auth': `FIS ${authToken}`\n });\n}\n\nfunction getBody({\n p256dh,\n auth,\n endpoint,\n vapidKey\n}: SubscriptionOptions): ApiRequestBody {\n const body: ApiRequestBody = {\n web: {\n endpoint,\n auth,\n p256dh\n }\n };\n\n if (vapidKey !== DEFAULT_VAPID_KEY) {\n body.web.applicationPubKey = vapidKey;\n }\n\n return body;\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { SubscriptionOptions, TokenDetails } from '../interfaces/token-details';\nimport {\n arrayToBase64,\n base64ToArray\n} from '../helpers/array-base64-translator';\nimport { dbGet, dbRemove, dbSet } from './idb-manager';\nimport {\n requestDeleteToken,\n requestGetToken,\n requestUpdateToken\n} from './requests';\n\nimport { FirebaseInternalDependencies } from '../interfaces/internal-dependencies';\nimport { MessagingService } from '../messaging-service';\n\n// UpdateRegistration will be called once every week.\nconst TOKEN_EXPIRATION_MS = 7 * 24 * 60 * 60 * 1000; // 7 days\n\nexport async function getTokenInternal(\n messaging: MessagingService\n): Promise {\n const pushSubscription = await getPushSubscription(\n messaging.swRegistration!,\n messaging.vapidKey!\n );\n\n const subscriptionOptions: SubscriptionOptions = {\n vapidKey: messaging.vapidKey!,\n swScope: messaging.swRegistration!.scope,\n endpoint: pushSubscription.endpoint,\n auth: arrayToBase64(pushSubscription.getKey('auth')!),\n p256dh: arrayToBase64(pushSubscription.getKey('p256dh')!)\n };\n\n const tokenDetails = await dbGet(messaging.firebaseDependencies);\n if (!tokenDetails) {\n // No token, get a new one.\n return getNewToken(messaging.firebaseDependencies, subscriptionOptions);\n } else if (\n !isTokenValid(tokenDetails.subscriptionOptions!, subscriptionOptions)\n ) {\n // Invalid token, get a new one.\n try {\n await requestDeleteToken(\n messaging.firebaseDependencies!,\n tokenDetails.token\n );\n } catch (e) {\n // Suppress errors because of #2364\n console.warn(e);\n }\n\n return getNewToken(messaging.firebaseDependencies!, subscriptionOptions);\n } else if (Date.now() >= tokenDetails.createTime + TOKEN_EXPIRATION_MS) {\n // Weekly token refresh\n return updateToken(messaging, {\n token: tokenDetails.token,\n createTime: Date.now(),\n subscriptionOptions\n });\n } else {\n // Valid token, nothing to do.\n return tokenDetails.token;\n }\n}\n\n/**\n * This method deletes the token from the database, unsubscribes the token from FCM, and unregisters\n * the push subscription if it exists.\n */\nexport async function deleteTokenInternal(\n messaging: MessagingService\n): Promise {\n const tokenDetails = await dbGet(messaging.firebaseDependencies);\n if (tokenDetails) {\n await requestDeleteToken(\n messaging.firebaseDependencies,\n tokenDetails.token\n );\n await dbRemove(messaging.firebaseDependencies);\n }\n\n // Unsubscribe from the push subscription.\n const pushSubscription =\n await messaging.swRegistration!.pushManager.getSubscription();\n if (pushSubscription) {\n return pushSubscription.unsubscribe();\n }\n\n // If there's no SW, consider it a success.\n return true;\n}\n\nasync function updateToken(\n messaging: MessagingService,\n tokenDetails: TokenDetails\n): Promise {\n try {\n const updatedToken = await requestUpdateToken(\n messaging.firebaseDependencies,\n tokenDetails\n );\n\n const updatedTokenDetails: TokenDetails = {\n ...tokenDetails,\n token: updatedToken,\n createTime: Date.now()\n };\n\n await dbSet(messaging.firebaseDependencies, updatedTokenDetails);\n return updatedToken;\n } catch (e) {\n await deleteTokenInternal(messaging);\n throw e;\n }\n}\n\nasync function getNewToken(\n firebaseDependencies: FirebaseInternalDependencies,\n subscriptionOptions: SubscriptionOptions\n): Promise {\n const token = await requestGetToken(\n firebaseDependencies,\n subscriptionOptions\n );\n const tokenDetails: TokenDetails = {\n token,\n createTime: Date.now(),\n subscriptionOptions\n };\n await dbSet(firebaseDependencies, tokenDetails);\n return tokenDetails.token;\n}\n\n/**\n * Gets a PushSubscription for the current user.\n */\nasync function getPushSubscription(\n swRegistration: ServiceWorkerRegistration,\n vapidKey: string\n): Promise {\n const subscription = await swRegistration.pushManager.getSubscription();\n if (subscription) {\n return subscription;\n }\n\n return swRegistration.pushManager.subscribe({\n userVisibleOnly: true,\n // Chrome <= 75 doesn't support base64-encoded VAPID key. For backward compatibility, VAPID key\n // submitted to pushManager#subscribe must be of type Uint8Array.\n applicationServerKey: base64ToArray(vapidKey)\n });\n}\n\n/**\n * Checks if the saved tokenDetails object matches the configuration provided.\n */\nfunction isTokenValid(\n dbOptions: SubscriptionOptions,\n currentOptions: SubscriptionOptions\n): boolean {\n const isVapidKeyEqual = currentOptions.vapidKey === dbOptions.vapidKey;\n const isEndpointEqual = currentOptions.endpoint === dbOptions.endpoint;\n const isAuthEqual = currentOptions.auth === dbOptions.auth;\n const isP256dhEqual = currentOptions.p256dh === dbOptions.p256dh;\n\n return isVapidKeyEqual && isEndpointEqual && isAuthEqual && isP256dhEqual;\n}\n", "/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { MessagePayload } from '../interfaces/public-types';\nimport { MessagePayloadInternal } from '../interfaces/internal-message-payload';\n\nexport function externalizePayload(\n internalPayload: MessagePayloadInternal\n): MessagePayload {\n const payload: MessagePayload = {\n from: internalPayload.from,\n // eslint-disable-next-line camelcase\n collapseKey: internalPayload.collapse_key,\n // eslint-disable-next-line camelcase\n messageId: internalPayload.fcmMessageId\n } as MessagePayload;\n\n propagateNotificationPayload(payload, internalPayload);\n propagateDataPayload(payload, internalPayload);\n propagateFcmOptions(payload, internalPayload);\n\n return payload;\n}\n\nfunction propagateNotificationPayload(\n payload: MessagePayload,\n messagePayloadInternal: MessagePayloadInternal\n): void {\n if (!messagePayloadInternal.notification) {\n return;\n }\n\n payload.notification = {};\n\n const title = messagePayloadInternal.notification!.title;\n if (!!title) {\n payload.notification!.title = title;\n }\n\n const body = messagePayloadInternal.notification!.body;\n if (!!body) {\n payload.notification!.body = body;\n }\n\n const image = messagePayloadInternal.notification!.image;\n if (!!image) {\n payload.notification!.image = image;\n }\n}\n\nfunction propagateDataPayload(\n payload: MessagePayload,\n messagePayloadInternal: MessagePayloadInternal\n): void {\n if (!messagePayloadInternal.data) {\n return;\n }\n\n payload.data = messagePayloadInternal.data as { [key: string]: string };\n}\n\nfunction propagateFcmOptions(\n payload: MessagePayload,\n messagePayloadInternal: MessagePayloadInternal\n): void {\n // fcmOptions.link value is written into notification.click_action. see more in b/232072111\n if (\n !messagePayloadInternal.fcmOptions &&\n !messagePayloadInternal.notification?.click_action\n ) {\n return;\n }\n\n payload.fcmOptions = {};\n\n const link =\n messagePayloadInternal.fcmOptions?.link ??\n messagePayloadInternal.notification?.click_action;\n\n if (!!link) {\n payload.fcmOptions!.link = link;\n }\n\n // eslint-disable-next-line camelcase\n const analyticsLabel = messagePayloadInternal.fcmOptions?.analytics_label;\n if (!!analyticsLabel) {\n payload.fcmOptions!.analyticsLabel = analyticsLabel;\n }\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { CONSOLE_CAMPAIGN_ID } from '../util/constants';\nimport { ConsoleMessageData } from '../interfaces/internal-message-payload';\n\nexport function isConsoleMessage(data: unknown): data is ConsoleMessageData {\n // This message has a campaign ID, meaning it was sent using the Firebase Console.\n return typeof data === 'object' && !!data && CONSOLE_CAMPAIGN_ID in data;\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/** Returns a promise that resolves after given time passes. */\nexport function sleep(ms: number): Promise {\n return new Promise(resolve => {\n setTimeout(resolve, ms);\n });\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n DEFAULT_BACKOFF_TIME_MS,\n EVENT_MESSAGE_DELIVERED,\n FCM_LOG_SOURCE,\n LOG_INTERVAL_IN_MS,\n MAX_NUMBER_OF_EVENTS_PER_LOG_REQUEST,\n MAX_RETRIES,\n MessageType,\n SDK_PLATFORM_WEB\n} from '../util/constants';\nimport {\n FcmEvent,\n LogEvent,\n LogRequest,\n LogResponse\n} from '../interfaces/logging-types';\n\nimport { MessagePayloadInternal } from '../interfaces/internal-message-payload';\nimport { MessagingService } from '../messaging-service';\n\nconst FIRELOG_ENDPOINT = _mergeStrings(\n 'hts/frbslgigp.ogepscmv/ieo/eaylg',\n 'tp:/ieaeogn-agolai.o/1frlglgc/o'\n);\n\nconst FCM_TRANSPORT_KEY = _mergeStrings(\n 'AzSCbw63g1R0nCw85jG8',\n 'Iaya3yLKwmgvh7cF0q4'\n);\n\nexport function startLoggingService(messaging: MessagingService): void {\n if (!messaging.isLogServiceStarted) {\n _processQueue(messaging, LOG_INTERVAL_IN_MS);\n messaging.isLogServiceStarted = true;\n }\n}\n\n/**\n *\n * @param messaging the messaging instance.\n * @param offsetInMs this method execute after `offsetInMs` elapsed .\n */\nexport function _processQueue(\n messaging: MessagingService,\n offsetInMs: number\n): void {\n setTimeout(async () => {\n if (!messaging.deliveryMetricsExportedToBigQueryEnabled) {\n // flush events and terminate logging service\n messaging.logEvents = [];\n messaging.isLogServiceStarted = false;\n\n return;\n }\n\n if (!messaging.logEvents.length) {\n return _processQueue(messaging, LOG_INTERVAL_IN_MS);\n }\n\n await _dispatchLogEvents(messaging);\n }, offsetInMs);\n}\n\nexport async function _dispatchLogEvents(\n messaging: MessagingService\n): Promise {\n for (\n let i = 0, n = messaging.logEvents.length;\n i < n;\n i += MAX_NUMBER_OF_EVENTS_PER_LOG_REQUEST\n ) {\n const logRequest = _createLogRequest(\n messaging.logEvents.slice(i, i + MAX_NUMBER_OF_EVENTS_PER_LOG_REQUEST)\n );\n\n let retryCount = 0,\n response = {} as Response;\n\n do {\n try {\n response = await fetch(\n FIRELOG_ENDPOINT.concat('?key=', FCM_TRANSPORT_KEY),\n {\n method: 'POST',\n body: JSON.stringify(logRequest)\n }\n );\n\n // don't retry on 200s or non retriable errors\n if (response.ok || (!response.ok && !isRetriableError(response))) {\n break;\n }\n\n if (!response.ok && isRetriableError(response)) {\n // rethrow to retry with quota\n throw new Error(\n 'a retriable Non-200 code is returned in fetch to Firelog endpoint. Retry'\n );\n }\n } catch (error) {\n const isLastAttempt = retryCount === MAX_RETRIES;\n if (isLastAttempt) {\n // existing the do-while interactive retry logic because retry quota has reached.\n break;\n }\n }\n\n let delayInMs: number;\n try {\n delayInMs = Number(\n ((await response.json()) as LogResponse).nextRequestWaitMillis\n );\n } catch (e) {\n delayInMs = DEFAULT_BACKOFF_TIME_MS;\n }\n\n await new Promise(resolve => setTimeout(resolve, delayInMs));\n\n retryCount++;\n } while (retryCount < MAX_RETRIES);\n }\n\n messaging.logEvents = [];\n // schedule for next logging\n _processQueue(messaging, LOG_INTERVAL_IN_MS);\n}\n\nfunction isRetriableError(response: Response): boolean {\n const httpStatus = response.status;\n\n return (\n httpStatus === 429 ||\n httpStatus === 500 ||\n httpStatus === 503 ||\n httpStatus === 504\n );\n}\n\nexport async function stageLog(\n messaging: MessagingService,\n internalPayload: MessagePayloadInternal\n): Promise {\n const fcmEvent = createFcmEvent(\n internalPayload,\n await messaging.firebaseDependencies.installations.getId()\n );\n\n createAndEnqueueLogEvent(messaging, fcmEvent);\n}\n\nfunction createFcmEvent(\n internalPayload: MessagePayloadInternal,\n fid: string\n): FcmEvent {\n const fcmEvent = {} as FcmEvent;\n\n /* eslint-disable camelcase */\n // some fields should always be non-null. Still check to ensure.\n if (!!internalPayload.from) {\n fcmEvent.project_number = internalPayload.from;\n }\n\n if (!!internalPayload.fcmMessageId) {\n fcmEvent.message_id = internalPayload.fcmMessageId;\n }\n\n fcmEvent.instance_id = fid;\n\n if (!!internalPayload.notification) {\n fcmEvent.message_type = MessageType.DISPLAY_NOTIFICATION.toString();\n } else {\n fcmEvent.message_type = MessageType.DATA_MESSAGE.toString();\n }\n\n fcmEvent.sdk_platform = SDK_PLATFORM_WEB.toString();\n fcmEvent.package_name = self.origin.replace(/(^\\w+:|^)\\/\\//, '');\n\n if (!!internalPayload.collapse_key) {\n fcmEvent.collapse_key = internalPayload.collapse_key;\n }\n\n fcmEvent.event = EVENT_MESSAGE_DELIVERED.toString();\n\n if (!!internalPayload.fcmOptions?.analytics_label) {\n fcmEvent.analytics_label = internalPayload.fcmOptions?.analytics_label;\n }\n\n /* eslint-enable camelcase */\n return fcmEvent;\n}\n\nfunction createAndEnqueueLogEvent(\n messaging: MessagingService,\n fcmEvent: FcmEvent\n): void {\n const logEvent = {} as LogEvent;\n\n /* eslint-disable camelcase */\n logEvent.event_time_ms = Math.floor(Date.now()).toString();\n logEvent.source_extension_json_proto3 = JSON.stringify(fcmEvent);\n // eslint-disable-next-line camelcase\n\n messaging.logEvents.push(logEvent);\n}\n\nexport function _createLogRequest(logEventQueue: LogEvent[]): LogRequest {\n const logRequest = {} as LogRequest;\n\n /* eslint-disable camelcase */\n logRequest.log_source = FCM_LOG_SOURCE.toString();\n logRequest.log_event = logEventQueue;\n /* eslint-enable camelcase */\n\n return logRequest;\n}\n\nexport function _mergeStrings(s1: string, s2: string): string {\n const resultArray = [];\n for (let i = 0; i < s1.length; i++) {\n resultArray.push(s1.charAt(i));\n if (i < s2.length) {\n resultArray.push(s2.charAt(i));\n }\n }\n\n return resultArray.join('');\n}\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { DEFAULT_VAPID_KEY, FCM_MSG } from '../util/constants';\nimport {\n MessagePayloadInternal,\n MessageType,\n NotificationPayloadInternal\n} from '../interfaces/internal-message-payload';\nimport {\n NotificationEvent,\n PushEvent,\n PushSubscriptionChangeEvent,\n ServiceWorkerGlobalScope,\n WindowClient\n} from '../util/sw-types';\nimport {\n deleteTokenInternal,\n getTokenInternal\n} from '../internals/token-manager';\n\nimport { MessagingService } from '../messaging-service';\nimport { dbGet } from '../internals/idb-manager';\nimport { externalizePayload } from '../helpers/externalizePayload';\nimport { isConsoleMessage } from '../helpers/is-console-message';\nimport { sleep } from '../helpers/sleep';\nimport { stageLog } from '../helpers/logToFirelog';\n\n// Let TS know that this is a service worker\ndeclare const self: ServiceWorkerGlobalScope;\n\nexport async function onSubChange(\n event: PushSubscriptionChangeEvent,\n messaging: MessagingService\n): Promise {\n const { newSubscription } = event;\n if (!newSubscription) {\n // Subscription revoked, delete token\n await deleteTokenInternal(messaging);\n return;\n }\n\n const tokenDetails = await dbGet(messaging.firebaseDependencies);\n await deleteTokenInternal(messaging);\n\n messaging.vapidKey =\n tokenDetails?.subscriptionOptions?.vapidKey ?? DEFAULT_VAPID_KEY;\n await getTokenInternal(messaging);\n}\n\nexport async function onPush(\n event: PushEvent,\n messaging: MessagingService\n): Promise {\n const internalPayload = getMessagePayloadInternal(event);\n if (!internalPayload) {\n // Failed to get parsed MessagePayload from the PushEvent. Skip handling the push.\n return;\n }\n\n // log to Firelog with user consent\n if (messaging.deliveryMetricsExportedToBigQueryEnabled) {\n await stageLog(messaging, internalPayload);\n }\n\n // foreground handling: eventually passed to onMessage hook\n const clientList = await getClientList();\n if (hasVisibleClients(clientList)) {\n return sendMessagePayloadInternalToWindows(clientList, internalPayload);\n }\n\n // background handling: display if possible and pass to onBackgroundMessage hook\n if (!!internalPayload.notification) {\n await showNotification(wrapInternalPayload(internalPayload));\n }\n\n if (!messaging) {\n return;\n }\n\n if (!!messaging.onBackgroundMessageHandler) {\n const payload = externalizePayload(internalPayload);\n\n if (typeof messaging.onBackgroundMessageHandler === 'function') {\n await messaging.onBackgroundMessageHandler(payload);\n } else {\n messaging.onBackgroundMessageHandler.next(payload);\n }\n }\n}\n\nexport async function onNotificationClick(\n event: NotificationEvent\n): Promise {\n const internalPayload: MessagePayloadInternal =\n event.notification?.data?.[FCM_MSG];\n\n if (!internalPayload) {\n return;\n } else if (event.action) {\n // User clicked on an action button. This will allow developers to act on action button clicks\n // by using a custom onNotificationClick listener that they define.\n return;\n }\n\n // Prevent other listeners from receiving the event\n event.stopImmediatePropagation();\n event.notification.close();\n\n // Note clicking on a notification with no link set will focus the Chrome's current tab.\n const link = getLink(internalPayload);\n if (!link) {\n return;\n }\n\n // FM should only open/focus links from app's origin.\n const url = new URL(link, self.location.href);\n const originUrl = new URL(self.location.origin);\n\n if (url.host !== originUrl.host) {\n return;\n }\n\n let client = await getWindowClient(url);\n\n if (!client) {\n client = await self.clients.openWindow(link);\n\n // Wait three seconds for the client to initialize and set up the message handler so that it\n // can receive the message.\n await sleep(3000);\n } else {\n client = await client.focus();\n }\n\n if (!client) {\n // Window Client will not be returned if it's for a third party origin.\n return;\n }\n\n internalPayload.messageType = MessageType.NOTIFICATION_CLICKED;\n internalPayload.isFirebaseMessaging = true;\n return client.postMessage(internalPayload);\n}\n\nfunction wrapInternalPayload(\n internalPayload: MessagePayloadInternal\n): NotificationPayloadInternal {\n const wrappedInternalPayload: NotificationPayloadInternal = {\n ...(internalPayload.notification as unknown as NotificationPayloadInternal)\n };\n\n // Put the message payload under FCM_MSG name so we can identify the notification as being an FCM\n // notification vs a notification from somewhere else (i.e. normal web push or developer generated\n // notification).\n wrappedInternalPayload.data = {\n [FCM_MSG]: internalPayload\n };\n\n return wrappedInternalPayload;\n}\n\nfunction getMessagePayloadInternal({\n data\n}: PushEvent): MessagePayloadInternal | null {\n if (!data) {\n return null;\n }\n\n try {\n return data.json();\n } catch (err) {\n // Not JSON so not an FCM message.\n return null;\n }\n}\n\n/**\n * @param url The URL to look for when focusing a client.\n * @return Returns an existing window client or a newly opened WindowClient.\n */\nasync function getWindowClient(url: URL): Promise {\n const clientList = await getClientList();\n\n for (const client of clientList) {\n const clientUrl = new URL(client.url, self.location.href);\n\n if (url.host === clientUrl.host) {\n return client;\n }\n }\n\n return null;\n}\n\n/**\n * @returns If there is currently a visible WindowClient, this method will resolve to true,\n * otherwise false.\n */\nfunction hasVisibleClients(clientList: WindowClient[]): boolean {\n return clientList.some(\n client =>\n client.visibilityState === 'visible' &&\n // Ignore chrome-extension clients as that matches the background pages of extensions, which\n // are always considered visible for some reason.\n !client.url.startsWith('chrome-extension://')\n );\n}\n\nfunction sendMessagePayloadInternalToWindows(\n clientList: WindowClient[],\n internalPayload: MessagePayloadInternal\n): void {\n internalPayload.isFirebaseMessaging = true;\n internalPayload.messageType = MessageType.PUSH_RECEIVED;\n\n for (const client of clientList) {\n client.postMessage(internalPayload);\n }\n}\n\nfunction getClientList(): Promise {\n return self.clients.matchAll({\n type: 'window',\n includeUncontrolled: true\n // TS doesn't know that \"type: 'window'\" means it'll return WindowClient[]\n }) as Promise;\n}\n\nfunction showNotification(\n notificationPayloadInternal: NotificationPayloadInternal\n): Promise {\n // Note: Firefox does not support the maxActions property.\n // https://developer.mozilla.org/en-US/docs/Web/API/notification/maxActions\n const { actions } = notificationPayloadInternal;\n const { maxActions } = Notification;\n if (actions && maxActions && actions.length > maxActions) {\n console.warn(\n `This browser only supports ${maxActions} actions. The remaining actions will not be displayed.`\n );\n }\n\n return self.registration.showNotification(\n /* title= */ notificationPayloadInternal.title ?? '',\n notificationPayloadInternal\n );\n}\n\nfunction getLink(payload: MessagePayloadInternal): string | null {\n // eslint-disable-next-line camelcase\n const link = payload.fcmOptions?.link ?? payload.notification?.click_action;\n if (link) {\n return link;\n }\n\n if (isConsoleMessage(payload.data)) {\n // Notification created in the Firebase Console. Redirect to origin.\n return self.location.origin;\n } else {\n return null;\n }\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ERROR_FACTORY, ErrorCode } from '../util/errors';\nimport { FirebaseApp, FirebaseOptions } from '@firebase/app';\n\nimport { AppConfig } from '../interfaces/app-config';\nimport { FirebaseError } from '@firebase/util';\n\nexport function extractAppConfig(app: FirebaseApp): AppConfig {\n if (!app || !app.options) {\n throw getMissingValueError('App Configuration Object');\n }\n\n if (!app.name) {\n throw getMissingValueError('App Name');\n }\n\n // Required app config keys\n const configKeys: ReadonlyArray = [\n 'projectId',\n 'apiKey',\n 'appId',\n 'messagingSenderId'\n ];\n\n const { options } = app;\n for (const keyName of configKeys) {\n if (!options[keyName]) {\n throw getMissingValueError(keyName);\n }\n }\n\n return {\n appName: app.name,\n projectId: options.projectId!,\n apiKey: options.apiKey!,\n appId: options.appId!,\n senderId: options.messagingSenderId!\n };\n}\n\nfunction getMissingValueError(valueName: string): FirebaseError {\n return ERROR_FACTORY.create(ErrorCode.MISSING_APP_CONFIG_VALUES, {\n valueName\n });\n}\n", "/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { FirebaseApp, _FirebaseService } from '@firebase/app';\nimport { MessagePayload, NextFn, Observer } from './interfaces/public-types';\n\nimport { FirebaseAnalyticsInternalName } from '@firebase/analytics-interop-types';\nimport { FirebaseInternalDependencies } from './interfaces/internal-dependencies';\nimport { LogEvent } from './interfaces/logging-types';\nimport { Provider } from '@firebase/component';\nimport { _FirebaseInstallationsInternal } from '@firebase/installations';\nimport { extractAppConfig } from './helpers/extract-app-config';\n\nexport class MessagingService implements _FirebaseService {\n readonly app!: FirebaseApp;\n readonly firebaseDependencies!: FirebaseInternalDependencies;\n\n swRegistration?: ServiceWorkerRegistration;\n vapidKey?: string;\n // logging is only done with end user consent. Default to false.\n deliveryMetricsExportedToBigQueryEnabled: boolean = false;\n\n onBackgroundMessageHandler:\n | NextFn\n | Observer\n | null = null;\n\n onMessageHandler: NextFn | Observer | null =\n null;\n\n logEvents: LogEvent[] = [];\n isLogServiceStarted: boolean = false;\n\n constructor(\n app: FirebaseApp,\n installations: _FirebaseInstallationsInternal,\n analyticsProvider: Provider\n ) {\n const appConfig = extractAppConfig(app);\n\n this.firebaseDependencies = {\n app,\n appConfig,\n installations,\n analyticsProvider\n };\n }\n\n _delete(): Promise {\n return Promise.resolve();\n }\n}\n", "/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n Component,\n ComponentContainer,\n ComponentType,\n InstanceFactory\n} from '@firebase/component';\nimport {\n onNotificationClick,\n onPush,\n onSubChange\n} from '../listeners/sw-listeners';\n\nimport { GetTokenOptions } from '../interfaces/public-types';\nimport { MessagingInternal } from '@firebase/messaging-interop-types';\nimport { MessagingService } from '../messaging-service';\nimport { ServiceWorkerGlobalScope } from '../util/sw-types';\nimport { _registerComponent, registerVersion } from '@firebase/app';\nimport { getToken } from '../api/getToken';\nimport { messageEventListener } from '../listeners/window-listener';\n\nimport { name, version } from '../../package.json';\n\nconst WindowMessagingFactory: InstanceFactory<'messaging'> = (\n container: ComponentContainer\n) => {\n const messaging = new MessagingService(\n container.getProvider('app').getImmediate(),\n container.getProvider('installations-internal').getImmediate(),\n container.getProvider('analytics-internal')\n );\n\n navigator.serviceWorker.addEventListener('message', e =>\n messageEventListener(messaging as MessagingService, e)\n );\n\n return messaging;\n};\n\nconst WindowMessagingInternalFactory: InstanceFactory<'messaging-internal'> = (\n container: ComponentContainer\n) => {\n const messaging = container\n .getProvider('messaging')\n .getImmediate() as MessagingService;\n\n const messagingInternal: MessagingInternal = {\n getToken: (options?: GetTokenOptions) => getToken(messaging, options)\n };\n\n return messagingInternal;\n};\n\ndeclare const self: ServiceWorkerGlobalScope;\nconst SwMessagingFactory: InstanceFactory<'messaging'> = (\n container: ComponentContainer\n) => {\n const messaging = new MessagingService(\n container.getProvider('app').getImmediate(),\n container.getProvider('installations-internal').getImmediate(),\n container.getProvider('analytics-internal')\n );\n\n self.addEventListener('push', e => {\n e.waitUntil(onPush(e, messaging as MessagingService));\n });\n self.addEventListener('pushsubscriptionchange', e => {\n e.waitUntil(onSubChange(e, messaging as MessagingService));\n });\n self.addEventListener('notificationclick', e => {\n e.waitUntil(onNotificationClick(e));\n });\n\n return messaging;\n};\n\nexport function registerMessagingInWindow(): void {\n _registerComponent(\n new Component('messaging', WindowMessagingFactory, ComponentType.PUBLIC)\n );\n\n _registerComponent(\n new Component(\n 'messaging-internal',\n WindowMessagingInternalFactory,\n ComponentType.PRIVATE\n )\n );\n\n registerVersion(name, version);\n // BUILD_TARGET will be replaced by values like esm5, esm2017, cjs5, etc during the compilation\n registerVersion(name, version, '__BUILD_TARGET__');\n}\n\n/**\n * The messaging instance registered in sw is named differently than that of in client. This is\n * because both `registerMessagingInWindow` and `registerMessagingInSw` would be called in\n * `messaging-compat` and component with the same name can only be registered once.\n */\nexport function registerMessagingInSw(): void {\n _registerComponent(\n new Component('messaging-sw', SwMessagingFactory, ComponentType.PUBLIC)\n );\n}\n", "/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n areCookiesEnabled,\n isIndexedDBAvailable,\n validateIndexedDBOpenable\n} from '@firebase/util';\n\n/**\n * Checks if all required APIs exist in the browser.\n * @returns a Promise that resolves to a boolean.\n *\n * @public\n */\nexport async function isWindowSupported(): Promise {\n try {\n // This throws if open() is unsupported, so adding it to the conditional\n // statement below can cause an uncaught error.\n await validateIndexedDBOpenable();\n } catch (e) {\n return false;\n }\n // firebase-js-sdk/issues/2393 reveals that idb#open in Safari iframe and Firefox private browsing\n // might be prohibited to run. In these contexts, an error would be thrown during the messaging\n // instantiating phase, informing the developers to import/call isSupported for special handling.\n return (\n typeof window !== 'undefined' &&\n isIndexedDBAvailable() &&\n areCookiesEnabled() &&\n 'serviceWorker' in navigator &&\n 'PushManager' in window &&\n 'Notification' in window &&\n 'fetch' in window &&\n ServiceWorkerRegistration.prototype.hasOwnProperty('showNotification') &&\n PushSubscription.prototype.hasOwnProperty('getKey')\n );\n}\n\n/**\n * Checks whether all required APIs exist within SW Context\n * @returns a Promise that resolves to a boolean.\n *\n * @public\n */\nexport async function isSwSupported(): Promise {\n // firebase-js-sdk/issues/2393 reveals that idb#open in Safari iframe and Firefox private browsing\n // might be prohibited to run. In these contexts, an error would be thrown during the messaging\n // instantiating phase, informing the developers to import/call isSupported for special handling.\n return (\n isIndexedDBAvailable() &&\n (await validateIndexedDBOpenable()) &&\n 'PushManager' in self &&\n 'Notification' in self &&\n ServiceWorkerRegistration.prototype.hasOwnProperty('showNotification') &&\n PushSubscription.prototype.hasOwnProperty('getKey')\n );\n}\n", "/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ERROR_FACTORY, ErrorCode } from '../util/errors';\n\nimport {\n MessagePayload,\n NextFn,\n Observer,\n Unsubscribe\n} from '../interfaces/public-types';\nimport { MessagingService } from '../messaging-service';\n\nexport function onBackgroundMessage(\n messaging: MessagingService,\n nextOrObserver: NextFn | Observer\n): Unsubscribe {\n if (self.document !== undefined) {\n throw ERROR_FACTORY.create(ErrorCode.AVAILABLE_IN_SW);\n }\n\n messaging.onBackgroundMessageHandler = nextOrObserver;\n\n return () => {\n messaging.onBackgroundMessageHandler = null;\n };\n}\n", "/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Messaging } from '../interfaces/public-types';\nimport { MessagingService } from '../messaging-service';\n\nexport function _setDeliveryMetricsExportedToBigQueryEnabled(\n messaging: Messaging,\n enable: boolean\n): void {\n (messaging as MessagingService).deliveryMetricsExportedToBigQueryEnabled =\n enable;\n}\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ERROR_FACTORY, ErrorCode } from './util/errors';\nimport { FirebaseApp, _getProvider, getApp } from '@firebase/app';\nimport {\n GetTokenOptions,\n MessagePayload,\n Messaging\n} from './interfaces/public-types';\nimport {\n NextFn,\n Observer,\n Unsubscribe,\n getModularInstance\n} from '@firebase/util';\nimport { isSwSupported, isWindowSupported } from './api/isSupported';\n\nimport { MessagingService } from './messaging-service';\nimport { deleteToken as _deleteToken } from './api/deleteToken';\nimport { getToken as _getToken } from './api/getToken';\nimport { onBackgroundMessage as _onBackgroundMessage } from './api/onBackgroundMessage';\nimport { onMessage as _onMessage } from './api/onMessage';\nimport { _setDeliveryMetricsExportedToBigQueryEnabled } from './api/setDeliveryMetricsExportedToBigQueryEnabled';\n\n/**\n * Retrieves a Firebase Cloud Messaging instance.\n *\n * @returns The Firebase Cloud Messaging instance associated with the provided firebase app.\n *\n * @public\n */\nexport function getMessagingInWindow(app: FirebaseApp = getApp()): Messaging {\n // Conscious decision to make this async check non-blocking during the messaging instance\n // initialization phase for performance consideration. An error would be thrown latter for\n // developer's information. Developers can then choose to import and call `isSupported` for\n // special handling.\n isWindowSupported().then(\n isSupported => {\n // If `isWindowSupported()` resolved, but returned false.\n if (!isSupported) {\n throw ERROR_FACTORY.create(ErrorCode.UNSUPPORTED_BROWSER);\n }\n },\n _ => {\n // If `isWindowSupported()` rejected.\n throw ERROR_FACTORY.create(ErrorCode.INDEXED_DB_UNSUPPORTED);\n }\n );\n return _getProvider(getModularInstance(app), 'messaging').getImmediate();\n}\n\n/**\n * Retrieves a Firebase Cloud Messaging instance.\n *\n * @returns The Firebase Cloud Messaging instance associated with the provided firebase app.\n *\n * @public\n */\nexport function getMessagingInSw(app: FirebaseApp = getApp()): Messaging {\n // Conscious decision to make this async check non-blocking during the messaging instance\n // initialization phase for performance consideration. An error would be thrown latter for\n // developer's information. Developers can then choose to import and call `isSupported` for\n // special handling.\n isSwSupported().then(\n isSupported => {\n // If `isSwSupported()` resolved, but returned false.\n if (!isSupported) {\n throw ERROR_FACTORY.create(ErrorCode.UNSUPPORTED_BROWSER);\n }\n },\n _ => {\n // If `isSwSupported()` rejected.\n throw ERROR_FACTORY.create(ErrorCode.INDEXED_DB_UNSUPPORTED);\n }\n );\n return _getProvider(getModularInstance(app), 'messaging-sw').getImmediate();\n}\n\n/**\n * Subscribes the {@link Messaging} instance to push notifications. Returns an Firebase Cloud\n * Messaging registration token that can be used to send push messages to that {@link Messaging}\n * instance.\n *\n * If a notification permission isn't already granted, this method asks the user for permission. The\n * returned promise rejects if the user does not allow the app to show notifications.\n *\n * @param messaging - The {@link Messaging} instance.\n * @param options - Provides an optional vapid key and an optinoal service worker registration\n *\n * @returns The promise resolves with an FCM registration token.\n *\n * @public\n */\nexport async function getToken(\n messaging: Messaging,\n options?: GetTokenOptions\n): Promise {\n messaging = getModularInstance(messaging);\n return _getToken(messaging as MessagingService, options);\n}\n\n/**\n * Deletes the registration token associated with this {@link Messaging} instance and unsubscribes\n * the {@link Messaging} instance from the push subscription.\n *\n * @param messaging - The {@link Messaging} instance.\n *\n * @returns The promise resolves when the token has been successfully deleted.\n *\n * @public\n */\nexport function deleteToken(messaging: Messaging): Promise {\n messaging = getModularInstance(messaging);\n return _deleteToken(messaging as MessagingService);\n}\n\n/**\n * When a push message is received and the user is currently on a page for your origin, the\n * message is passed to the page and an `onMessage()` event is dispatched with the payload of\n * the push message.\n *\n *\n * @param messaging - The {@link Messaging} instance.\n * @param nextOrObserver - This function, or observer object with `next` defined,\n * is called when a message is received and the user is currently viewing your page.\n * @returns To stop listening for messages execute this returned function.\n *\n * @public\n */\nexport function onMessage(\n messaging: Messaging,\n nextOrObserver: NextFn | Observer\n): Unsubscribe {\n messaging = getModularInstance(messaging);\n return _onMessage(messaging as MessagingService, nextOrObserver);\n}\n\n/**\n * Called when a message is received while the app is in the background. An app is considered to be\n * in the background if no active window is displayed.\n *\n * @param messaging - The {@link Messaging} instance.\n * @param nextOrObserver - This function, or observer object with `next` defined, is called when a\n * message is received and the app is currently in the background.\n *\n * @returns To stop listening for messages execute this returned function\n *\n * @public\n */\nexport function onBackgroundMessage(\n messaging: Messaging,\n nextOrObserver: NextFn | Observer\n): Unsubscribe {\n messaging = getModularInstance(messaging);\n return _onBackgroundMessage(messaging as MessagingService, nextOrObserver);\n}\n\n/**\n * Enables or disables Firebase Cloud Messaging message delivery metrics export to BigQuery. By\n * default, message delivery metrics are not exported to BigQuery. Use this method to enable or\n * disable the export at runtime.\n *\n * @param messaging - The `FirebaseMessaging` instance.\n * @param enable - Whether Firebase Cloud Messaging should export message delivery metrics to\n * BigQuery.\n *\n * @public\n */\nexport function experimentalSetDeliveryMetricsExportedToBigQueryEnabled(\n messaging: Messaging,\n enable: boolean\n): void {\n messaging = getModularInstance(messaging);\n return _setDeliveryMetricsExportedToBigQueryEnabled(messaging, enable);\n}\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport '@firebase/installations';\n\nimport { Messaging } from './interfaces/public-types';\nimport { registerMessagingInSw } from './helpers/register';\n\nexport * from './interfaces/public-types';\nexport {\n onBackgroundMessage,\n getMessagingInSw as getMessaging,\n experimentalSetDeliveryMetricsExportedToBigQueryEnabled\n} from './api';\nexport { isSwSupported as isSupported } from './api/isSupported';\n\ndeclare module '@firebase/component' {\n interface NameServiceMapping {\n 'messaging-sw': Messaging;\n }\n}\n\nregisterMessagingInSw();\n", "import { initializeApp } from 'firebase/app';\nimport {\n experimentalSetDeliveryMetricsExportedToBigQueryEnabled,\n getMessaging,\n isSupported,\n onBackgroundMessage\n} from 'firebase/messaging/sw';\n\ndeclare var self: ServiceWorkerGlobalScope;\n\nself.addEventListener('install', (event) => {\n console.log(self);\n console.log(event);\n});\n\nconst app = initializeApp({\n apiKey: 'AIzaSyAgUhHU8wSJgO5MVNy95tMT07NEjzMOfz0',\n authDomain: 'react-native-firebase-testing.firebaseapp.com',\n databaseURL: 'https://react-native-firebase-testing.firebaseio.com',\n projectId: 'react-native-firebase-testing',\n storageBucket: 'react-native-firebase-testing.appspot.com',\n messagingSenderId: '448618578101',\n appId: '1:448618578101:web:ecaffe2bc4511738',\n});\n\nisSupported().then((isSupported) => {\n if (isSupported) {\n const messaging = getMessaging(app);\n\n experimentalSetDeliveryMetricsExportedToBigQueryEnabled(messaging, true);\n\n console.log('experimental working');\n\n onBackgroundMessage(messaging, ({ notification: notification }) => {\n const { title, body, image } = notification ?? {};\n\n if (!title) {\n return;\n }\n\n self.registration.showNotification(title, {\n body,\n icon: image || '/assets/icons/icon-72x72.png',\n });\n });\n }\n});\n"], + "mappings": "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", "names": ["stringToByteArray", "str", "out", "p", "i", "c", "byteArrayToString", "bytes", "pos", "c1", "c2", "c3", "c4", "base64", "input", "webSafe", "byteToCharMap", "output", "byte1", "haveByte2", "byte2", "haveByte3", "byte3", "outByte1", "outByte2", "outByte3", "outByte4", "charToByteMap", "byte4", "base64Encode", "utf8Bytes", "base64urlEncodeWithoutPadding", "Deferred", "resolve", "reject", "callback", "error", "value", "isIndexedDBAvailable", "validateIndexedDBOpenable", "resolve", "reject", "preExist", "DB_CHECK_NAME", "request", "_a", "error", "ERROR_NAME", "FirebaseError", "code", "message", "customData", "ErrorFactory", "service", "serviceName", "errors", "data", "fullCode", "template", "replaceTemplate", "fullMessage", "PATTERN", "_", "key", "value", "deepEqual", "a", "b", "aKeys", "bKeys", "k", "aProp", "bProp", "isObject", "thing", "MAX_VALUE_MILLIS", "getModularInstance", "service", "Component", "name", "instanceFactory", "type", "mode", "multipleInstances", "props", "callback", "DEFAULT_ENTRY_NAME", "Provider", "container", "identifier", "normalizedIdentifier", "deferred", "Deferred", "instance", "options", "optional", "_a", "e", "component", "isComponentEager", "instanceIdentifier", "instanceDeferred", "services", "service", "opts", "normalizedDeferredIdentifier", "existingCallbacks", "existingInstance", "callbacks", "normalizeIdentifierForFactory", "ComponentContainer", "provider", "instances", "LogLevel", "levelStringToEnum", "defaultLogLevel", "ConsoleMethod", "defaultLogHandler", "instance", "logType", "args", "now", "method", "Logger", "name", "val", "instanceOfAny", "object", "constructors", "c", "idbProxyableTypes", "cursorAdvanceMethods", "getIdbProxyableTypes", "getCursorAdvanceMethods", "cursorRequestMap", "transactionDoneMap", "transactionStoreNamesMap", "transformCache", "reverseTransformCache", "promisifyRequest", "request", "promise", "resolve", "reject", "unlisten", "success", "error", "wrap", "value", "cacheDonePromiseForTransaction", "tx", "done", "complete", "idbProxyTraps", "target", "prop", "receiver", "replaceTraps", "callback", "wrapFunction", "func", "storeNames", "args", "unwrap", "transformCachableValue", "newValue", "openDB", "name", "version", "blocked", "upgrade", "blocking", "terminated", "request", "openPromise", "wrap", "event", "db", "deleteDB", "readMethods", "writeMethods", "cachedMethods", "getMethod", "target", "prop", "targetFuncName", "useIndex", "isWrite", "method", "storeName", "args", "tx", "replaceTraps", "oldTraps", "receiver", "PlatformLoggerServiceImpl", "container", "provider", "isVersionServiceProvider", "service", "logString", "component", "logger", "Logger", "DEFAULT_ENTRY_NAME", "PLATFORM_LOG_STRING", "appName", "appCompatName", "analyticsName", "analyticsCompatName", "appCheckName", "appCheckCompatName", "authName", "authCompatName", "databaseName", "databaseCompatName", "functionsName", "functionsCompatName", "installationsName", "installationsCompatName", "messagingName", "messagingCompatName", "performanceName", "performanceCompatName", "remoteConfigName", "remoteConfigCompatName", "storageName", "storageCompatName", "firestoreName", "firestoreCompatName", "packageName", "_apps", "_components", "_addComponent", "app", "component", "e", "logger", "_registerComponent", "component", "componentName", "_components", "logger", "app", "_apps", "_addComponent", "_getProvider", "name", "heartbeatController", "ERRORS", "ERROR_FACTORY", "ErrorFactory", "FirebaseAppImpl", "options", "config", "container", "Component", "val", "initializeApp", "options", "rawConfig", "config", "DEFAULT_ENTRY_NAME", "name", "ERROR_FACTORY", "existingApp", "_apps", "deepEqual", "container", "ComponentContainer", "component", "_components", "newApp", "FirebaseAppImpl", "getApp", "app", "registerVersion", "libraryKeyOrName", "version", "variant", "library", "_a", "PLATFORM_LOG_STRING", "libraryMismatch", "versionMismatch", "warning", "logger", "_registerComponent", "Component", "DB_NAME", "DB_VERSION", "STORE_NAME", "dbPromise", "getDbPromise", "openDB", "db", "oldVersion", "ERROR_FACTORY", "readHeartbeatsFromIndexedDB", "app", "computeKey", "e", "FirebaseError", "logger", "idbGetError", "_a", "writeHeartbeatsToIndexedDB", "heartbeatObject", "tx", "MAX_HEADER_BYTES", "STORED_HEARTBEAT_RETENTION_MAX_MILLIS", "HeartbeatServiceImpl", "container", "HeartbeatStorageImpl", "result", "agent", "date", "getUTCDateString", "singleDateHeartbeat", "hbTimestamp", "heartbeatsToSend", "unsentEntries", "extractHeartbeatsForHeader", "headerString", "base64urlEncodeWithoutPadding", "heartbeatsCache", "maxSize", "heartbeatEntry", "hb", "countBytes", "isIndexedDBAvailable", "validateIndexedDBOpenable", "heartbeatsObject", "existingHeartbeatsObject", "registerCoreComponents", "variant", "_registerComponent", "Component", "PlatformLoggerServiceImpl", "registerVersion", "name", "version", "registerVersion", "name", "version", "PENDING_TIMEOUT_MS", "PACKAGE_VERSION", "version", "INTERNAL_AUTH_VERSION", "INSTALLATIONS_API_URL", "TOKEN_EXPIRATION_BUFFER", "SERVICE", "SERVICE_NAME", "ERROR_DESCRIPTION_MAP", "ERROR_FACTORY", "ErrorFactory", "isServerError", "error", "FirebaseError", "getInstallationsEndpoint", "projectId", "extractAuthTokenInfoFromResponse", "response", "getExpiresInFromResponseExpiresIn", "getErrorFromResponse", "requestName", "errorData", "getHeaders", "apiKey", "getHeadersWithAuth", "appConfig", "refreshToken", "headers", "getAuthorizationHeader", "retryIfServerError", "fn", "result", "responseExpiresIn", "createInstallationRequest", "heartbeatServiceProvider", "fid", "endpoint", "heartbeatService", "heartbeatsHeader", "body", "request", "responseValue", "sleep", "ms", "resolve", "bufferToBase64UrlSafe", "array", "VALID_FID_PATTERN", "INVALID_FID", "generateFid", "fidByteArray", "encode", "getKey", "fidChangeCallbacks", "fidChanged", "key", "callFidChangeCallbacks", "broadcastFidChange", "callFidChangeCallbacks", "key", "fid", "callbacks", "fidChangeCallbacks", "callback", "broadcastFidChange", "channel", "getBroadcastChannel", "closeBroadcastChannel", "broadcastChannel", "DATABASE_NAME", "DATABASE_VERSION", "OBJECT_STORE_NAME", "dbPromise", "getDbPromise", "openDB", "db", "oldVersion", "set", "appConfig", "value", "getKey", "tx", "objectStore", "oldValue", "fidChanged", "remove", "update", "updateFn", "store", "newValue", "getInstallationEntry", "installations", "registrationPromise", "installationEntry", "oldEntry", "updateOrCreateInstallationEntry", "entryWithPromise", "triggerRegistrationIfNecessary", "INVALID_FID", "entry", "generateFid", "clearTimedOutRequest", "registrationPromiseWithError", "ERROR_FACTORY", "inProgressEntry", "registerInstallation", "waitUntilFidRegistration", "registeredInstallationEntry", "createInstallationRequest", "e", "isServerError", "updateInstallationRequest", "sleep", "hasInstallationRequestTimedOut", "PENDING_TIMEOUT_MS", "generateAuthTokenRequest", "heartbeatServiceProvider", "endpoint", "getGenerateAuthTokenEndpoint", "headers", "getHeadersWithAuth", "heartbeatService", "heartbeatsHeader", "body", "PACKAGE_VERSION", "request", "response", "retryIfServerError", "responseValue", "extractAuthTokenInfoFromResponse", "getErrorFromResponse", "getInstallationsEndpoint", "refreshAuthToken", "forceRefresh", "tokenPromise", "isEntryRegistered", "oldAuthToken", "isAuthTokenValid", "waitUntilAuthTokenRequest", "makeAuthTokenRequestInProgressEntry", "fetchAuthTokenFromServer", "updateAuthTokenRequest", "authToken", "hasAuthTokenRequestTimedOut", "updatedInstallationEntry", "isAuthTokenExpired", "now", "TOKEN_EXPIRATION_BUFFER", "inProgressAuthToken", "getId", "installationsImpl", "getToken", "completeInstallationRegistration", "extractAppConfig", "app", "getMissingValueError", "configKeys", "keyName", "valueName", "ERROR_FACTORY", "INSTALLATIONS_NAME", "INSTALLATIONS_NAME_INTERNAL", "publicFactory", "container", "appConfig", "heartbeatServiceProvider", "_getProvider", "internalFactory", "installations", "getId", "forceRefresh", "getToken", "registerInstallations", "_registerComponent", "Component", "registerVersion", "name", "version", "DEFAULT_VAPID_KEY", "ENDPOINT", "FCM_MSG", "CONSOLE_CAMPAIGN_ID", "SDK_PLATFORM_WEB", "EVENT_MESSAGE_DELIVERED", "MessageType", "arrayToBase64", "array", "uint8Array", "base64ToArray", "base64String", "padding", "base64", "rawData", "outputArray", "i", "OLD_DB_NAME", "OLD_DB_VERSION", "OLD_OBJECT_STORE_NAME", "migrateOldDatabase", "senderId", "db", "tokenDetails", "openDB", "oldVersion", "newVersion", "upgradeTransaction", "objectStore", "value", "oldDetails", "_a", "deleteDB", "checkTokenDetails", "subscriptionOptions", "DATABASE_NAME", "DATABASE_VERSION", "OBJECT_STORE_NAME", "dbPromise", "getDbPromise", "upgradeDb", "dbGet", "firebaseDependencies", "key", "getKey", "oldTokenDetails", "dbSet", "tx", "dbRemove", "appConfig", "ERROR_MAP", "ERROR_FACTORY", "ErrorFactory", "requestGetToken", "headers", "getHeaders", "body", "getBody", "subscribeOptions", "responseData", "getEndpoint", "err", "message", "requestUpdateToken", "updateOptions", "requestDeleteToken", "token", "unsubscribeOptions", "projectId", "installations", "authToken", "p256dh", "auth", "endpoint", "vapidKey", "TOKEN_EXPIRATION_MS", "getTokenInternal", "messaging", "pushSubscription", "getPushSubscription", "isTokenValid", "updateToken", "e", "getNewToken", "deleteTokenInternal", "updatedToken", "updatedTokenDetails", "swRegistration", "subscription", "dbOptions", "currentOptions", "isVapidKeyEqual", "isEndpointEqual", "isAuthEqual", "isP256dhEqual", "externalizePayload", "internalPayload", "payload", "propagateNotificationPayload", "propagateDataPayload", "propagateFcmOptions", "messagePayloadInternal", "title", "image", "link", "_c", "_b", "_d", "analyticsLabel", "_e", "isConsoleMessage", "data", "sleep", "ms", "resolve", "_mergeStrings", "stageLog", "fcmEvent", "createFcmEvent", "createAndEnqueueLogEvent", "fid", "logEvent", "s1", "s2", "resultArray", "onSubChange", "event", "newSubscription", "onPush", "getMessagePayloadInternal", "clientList", "getClientList", "hasVisibleClients", "sendMessagePayloadInternalToWindows", "showNotification", "wrapInternalPayload", "onNotificationClick", "getLink", "url", "originUrl", "client", "getWindowClient", "wrappedInternalPayload", "clientUrl", "notificationPayloadInternal", "actions", "maxActions", "extractAppConfig", "app", "getMissingValueError", "configKeys", "options", "keyName", "valueName", "MessagingService", "analyticsProvider", "SwMessagingFactory", "container", "registerMessagingInSw", "_registerComponent", "Component", "isSwSupported", "isIndexedDBAvailable", "validateIndexedDBOpenable", "onBackgroundMessage", "nextOrObserver", "_setDeliveryMetricsExportedToBigQueryEnabled", "enable", "getMessagingInSw", "getApp", "isSupported", "_", "_getProvider", "getModularInstance", "_onBackgroundMessage", "experimentalSetDeliveryMetricsExportedToBigQueryEnabled", "event", "app", "initializeApp", "isSwSupported", "isSupported", "messaging", "getMessagingInSw", "experimentalSetDeliveryMetricsExportedToBigQueryEnabled", "onBackgroundMessage", "notification", "title", "body", "image"] } From 411bd52d1c22e55afa77b8cebb89565560d9d3bc Mon Sep 17 00:00:00 2001 From: Guillaume Bernos Date: Wed, 5 Oct 2022 09:21:21 +0200 Subject: [PATCH 08/13] feat(messaging): export to BigQuery on web --- .../example/bundled-service-worker/firebase-messaging-sw.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/firebase_messaging/firebase_messaging/example/bundled-service-worker/firebase-messaging-sw.ts b/packages/firebase_messaging/firebase_messaging/example/bundled-service-worker/firebase-messaging-sw.ts index 16d1bde78c19..1a360c8ef8ab 100644 --- a/packages/firebase_messaging/firebase_messaging/example/bundled-service-worker/firebase-messaging-sw.ts +++ b/packages/firebase_messaging/firebase_messaging/example/bundled-service-worker/firebase-messaging-sw.ts @@ -29,8 +29,6 @@ isSupported().then((isSupported) => { experimentalSetDeliveryMetricsExportedToBigQueryEnabled(messaging, true); - console.log('experimental working'); - onBackgroundMessage(messaging, ({ notification: notification }) => { const { title, body, image } = notification ?? {}; From db73fb6b5c730dd69f0fe2c877dad2c473225560 Mon Sep 17 00:00:00 2001 From: Guillaume Bernos Date: Wed, 5 Oct 2022 09:31:30 +0200 Subject: [PATCH 09/13] feat(messaging): revert to old service worker with compat --- .../example/web/firebase-messaging-sw.js | 115 +++--------------- .../example/web/firebase-messaging-sw.js.map | 7 -- 2 files changed, 19 insertions(+), 103 deletions(-) delete mode 100644 packages/firebase_messaging/firebase_messaging/example/web/firebase-messaging-sw.js.map diff --git a/packages/firebase_messaging/firebase_messaging/example/web/firebase-messaging-sw.js b/packages/firebase_messaging/firebase_messaging/example/web/firebase-messaging-sw.js index 944b809b0a0b..aaf9b57acde4 100644 --- a/packages/firebase_messaging/firebase_messaging/example/web/firebase-messaging-sw.js +++ b/packages/firebase_messaging/firebase_messaging/example/web/firebase-messaging-sw.js @@ -1,96 +1,19 @@ -var ke=function(e){let t=[],n=0;for(let r=0;r>6|192,t[n++]=i&63|128):(i&64512)===55296&&r+1>18|240,t[n++]=i>>12&63|128,t[n++]=i>>6&63|128,t[n++]=i&63|128):(t[n++]=i>>12|224,t[n++]=i>>6&63|128,t[n++]=i&63|128)}return t},Et=function(e){let t=[],n=0,r=0;for(;n191&&i<224){let o=e[n++];t[r++]=String.fromCharCode((i&31)<<6|o&63)}else if(i>239&&i<365){let o=e[n++],s=e[n++],a=e[n++],u=((i&7)<<18|(o&63)<<12|(s&63)<<6|a&63)-65536;t[r++]=String.fromCharCode(55296+(u>>10)),t[r++]=String.fromCharCode(56320+(u&1023))}else{let o=e[n++],s=e[n++];t[r++]=String.fromCharCode((i&15)<<12|(o&63)<<6|s&63)}}return t.join("")},It={byteToCharMap_:null,charToByteMap_:null,byteToCharMapWebSafe_:null,charToByteMapWebSafe_:null,ENCODED_VALS_BASE:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",get ENCODED_VALS(){return this.ENCODED_VALS_BASE+"+/="},get ENCODED_VALS_WEBSAFE(){return this.ENCODED_VALS_BASE+"-_."},HAS_NATIVE_SUPPORT:typeof atob=="function",encodeByteArray(e,t){if(!Array.isArray(e))throw Error("encodeByteArray takes an array as a parameter");this.init_();let n=t?this.byteToCharMapWebSafe_:this.byteToCharMap_,r=[];for(let i=0;i>2,C=(o&3)<<4|a>>4,x=(a&15)<<2|f>>6,N=f&63;u||(N=64,s||(x=64)),r.push(n[c],n[C],n[x],n[N])}return r.join("")},encodeString(e,t){return this.HAS_NATIVE_SUPPORT&&!t?btoa(e):this.encodeByteArray(ke(e),t)},decodeString(e,t){return this.HAS_NATIVE_SUPPORT&&!t?atob(e):Et(this.decodeStringToByteArray(e,t))},decodeStringToByteArray(e,t){this.init_();let n=t?this.charToByteMapWebSafe_:this.charToByteMap_,r=[];for(let i=0;i>4;if(r.push(x),f!==64){let N=a<<4&240|f>>2;if(r.push(N),C!==64){let vt=f<<6&192|C;r.push(vt)}}}return r},init_(){if(!this.byteToCharMap_){this.byteToCharMap_={},this.charToByteMap_={},this.byteToCharMapWebSafe_={},this.charToByteMapWebSafe_={};for(let e=0;e=this.ENCODED_VALS_BASE.length&&(this.charToByteMap_[this.ENCODED_VALS_WEBSAFE.charAt(e)]=e,this.charToByteMapWebSafe_[this.ENCODED_VALS.charAt(e)]=e)}}},St=function(e){let t=ke(e);return It.encodeByteArray(t,!0)},G=function(e){return St(e).replace(/\./g,"")};var M=class{constructor(){this.reject=()=>{},this.resolve=()=>{},this.promise=new Promise((t,n)=>{this.resolve=t,this.reject=n})}wrapCallback(t){return(n,r)=>{n?this.reject(n):this.resolve(r),typeof t=="function"&&(this.promise.catch(()=>{}),t.length===1?t(n):t(n,r))}}};function B(){return typeof indexedDB=="object"}function R(){return new Promise((e,t)=>{try{let n=!0,r="validate-browser-context-for-indexeddb-analytics-module",i=self.indexedDB.open(r);i.onsuccess=()=>{i.result.close(),n||self.indexedDB.deleteDatabase(r),e(!0)},i.onupgradeneeded=()=>{n=!1},i.onerror=()=>{var o;t(((o=i.error)===null||o===void 0?void 0:o.message)||"")}}catch(n){t(n)}})}var At="FirebaseError",p=class extends Error{constructor(t,n,r){super(n),this.code=t,this.customData=r,this.name=At,Object.setPrototypeOf(this,p.prototype),Error.captureStackTrace&&Error.captureStackTrace(this,m.prototype.create)}},m=class{constructor(t,n,r){this.service=t,this.serviceName=n,this.errors=r}create(t,...n){let r=n[0]||{},i=`${this.service}/${t}`,o=this.errors[t],s=o?Tt(o,r):"Error",a=`${this.serviceName}: ${s} (${i}).`;return new p(i,a,r)}};function Tt(e,t){return e.replace(Dt,(n,r)=>{let i=t[r];return i!=null?String(i):`<${r}?>`})}var Dt=/\{\$([^}]+)}/g;function L(e,t){if(e===t)return!0;let n=Object.keys(e),r=Object.keys(t);for(let i of n){if(!r.includes(i))return!1;let o=e[i],s=t[i];if(Ce(o)&&Ce(s)){if(!L(o,s))return!1}else if(o!==s)return!1}for(let i of r)if(!n.includes(i))return!1;return!0}function Ce(e){return e!==null&&typeof e=="object"}var ri=4*60*60*1e3;function P(e){return e&&e._delegate?e._delegate:e}var d=class{constructor(t,n,r){this.name=t,this.instanceFactory=n,this.type=r,this.multipleInstances=!1,this.serviceProps={},this.instantiationMode="LAZY",this.onInstanceCreated=null}setInstantiationMode(t){return this.instantiationMode=t,this}setMultipleInstances(t){return this.multipleInstances=t,this}setServiceProps(t){return this.serviceProps=t,this}setInstanceCreatedCallback(t){return this.onInstanceCreated=t,this}};var _="[DEFAULT]";var J=class{constructor(t,n){this.name=t,this.container=n,this.component=null,this.instances=new Map,this.instancesDeferred=new Map,this.instancesOptions=new Map,this.onInitCallbacks=new Map}get(t){let n=this.normalizeInstanceIdentifier(t);if(!this.instancesDeferred.has(n)){let r=new M;if(this.instancesDeferred.set(n,r),this.isInitialized(n)||this.shouldAutoInitialize())try{let i=this.getOrInitializeService({instanceIdentifier:n});i&&r.resolve(i)}catch{}}return this.instancesDeferred.get(n).promise}getImmediate(t){var n;let r=this.normalizeInstanceIdentifier(t?.identifier),i=(n=t?.optional)!==null&&n!==void 0?n:!1;if(this.isInitialized(r)||this.shouldAutoInitialize())try{return this.getOrInitializeService({instanceIdentifier:r})}catch(o){if(i)return null;throw o}else{if(i)return null;throw Error(`Service ${this.name} is not available`)}}getComponent(){return this.component}setComponent(t){if(t.name!==this.name)throw Error(`Mismatching Component ${t.name} for Provider ${this.name}.`);if(this.component)throw Error(`Component for ${this.name} has already been provided`);if(this.component=t,!!this.shouldAutoInitialize()){if(kt(t))try{this.getOrInitializeService({instanceIdentifier:_})}catch{}for(let[n,r]of this.instancesDeferred.entries()){let i=this.normalizeInstanceIdentifier(n);try{let o=this.getOrInitializeService({instanceIdentifier:i});r.resolve(o)}catch{}}}}clearInstance(t=_){this.instancesDeferred.delete(t),this.instancesOptions.delete(t),this.instances.delete(t)}async delete(){let t=Array.from(this.instances.values());await Promise.all([...t.filter(n=>"INTERNAL"in n).map(n=>n.INTERNAL.delete()),...t.filter(n=>"_delete"in n).map(n=>n._delete())])}isComponentSet(){return this.component!=null}isInitialized(t=_){return this.instances.has(t)}getOptions(t=_){return this.instancesOptions.get(t)||{}}initialize(t={}){let{options:n={}}=t,r=this.normalizeInstanceIdentifier(t.instanceIdentifier);if(this.isInitialized(r))throw Error(`${this.name}(${r}) has already been initialized`);if(!this.isComponentSet())throw Error(`Component ${this.name} has not been registered yet`);let i=this.getOrInitializeService({instanceIdentifier:r,options:n});for(let[o,s]of this.instancesDeferred.entries()){let a=this.normalizeInstanceIdentifier(o);r===a&&s.resolve(i)}return i}onInit(t,n){var r;let i=this.normalizeInstanceIdentifier(n),o=(r=this.onInitCallbacks.get(i))!==null&&r!==void 0?r:new Set;o.add(t),this.onInitCallbacks.set(i,o);let s=this.instances.get(i);return s&&t(s,i),()=>{o.delete(t)}}invokeOnInitCallbacks(t,n){let r=this.onInitCallbacks.get(n);if(!!r)for(let i of r)try{i(t,n)}catch{}}getOrInitializeService({instanceIdentifier:t,options:n={}}){let r=this.instances.get(t);if(!r&&this.component&&(r=this.component.instanceFactory(this.container,{instanceIdentifier:Ct(t),options:n}),this.instances.set(t,r),this.instancesOptions.set(t,n),this.invokeOnInitCallbacks(r,t),this.component.onInstanceCreated))try{this.component.onInstanceCreated(this.container,t,r)}catch{}return r||null}normalizeInstanceIdentifier(t=_){return this.component?this.component.multipleInstances?t:_:t}shouldAutoInitialize(){return!!this.component&&this.component.instantiationMode!=="EXPLICIT"}};function Ct(e){return e===_?void 0:e}function kt(e){return e.instantiationMode==="EAGER"}var j=class{constructor(t){this.name=t,this.providers=new Map}addComponent(t){let n=this.getProvider(t.name);if(n.isComponentSet())throw new Error(`Component ${t.name} has already been registered with ${this.name}`);n.setComponent(t)}addOrOverwriteComponent(t){this.getProvider(t.name).isComponentSet()&&this.providers.delete(t.name),this.addComponent(t)}getProvider(t){if(this.providers.has(t))return this.providers.get(t);let n=new J(t,this);return this.providers.set(t,n),n}getProviders(){return Array.from(this.providers.values())}};var Ot=[],l;(function(e){e[e.DEBUG=0]="DEBUG",e[e.VERBOSE=1]="VERBOSE",e[e.INFO=2]="INFO",e[e.WARN=3]="WARN",e[e.ERROR=4]="ERROR",e[e.SILENT=5]="SILENT"})(l||(l={}));var xt={debug:l.DEBUG,verbose:l.VERBOSE,info:l.INFO,warn:l.WARN,error:l.ERROR,silent:l.SILENT},Nt=l.INFO,Mt={[l.DEBUG]:"log",[l.VERBOSE]:"log",[l.INFO]:"info",[l.WARN]:"warn",[l.ERROR]:"error"},Bt=(e,t,...n)=>{if(tt.some(n=>e instanceof n),Oe,xe;function Lt(){return Oe||(Oe=[IDBDatabase,IDBObjectStore,IDBIndex,IDBCursor,IDBTransaction])}function Pt(){return xe||(xe=[IDBCursor.prototype.advance,IDBCursor.prototype.continue,IDBCursor.prototype.continuePrimaryKey])}var Ne=new WeakMap,Q=new WeakMap,Me=new WeakMap,Y=new WeakMap,Z=new WeakMap;function jt(e){let t=new Promise((n,r)=>{let i=()=>{e.removeEventListener("success",o),e.removeEventListener("error",s)},o=()=>{n(g(e.result)),i()},s=()=>{r(e.error),i()};e.addEventListener("success",o),e.addEventListener("error",s)});return t.then(n=>{n instanceof IDBCursor&&Ne.set(n,e)}).catch(()=>{}),Z.set(t,e),t}function $t(e){if(Q.has(e))return;let t=new Promise((n,r)=>{let i=()=>{e.removeEventListener("complete",o),e.removeEventListener("error",s),e.removeEventListener("abort",s)},o=()=>{n(),i()},s=()=>{r(e.error||new DOMException("AbortError","AbortError")),i()};e.addEventListener("complete",o),e.addEventListener("error",s),e.addEventListener("abort",s)});Q.set(e,t)}var X={get(e,t,n){if(e instanceof IDBTransaction){if(t==="done")return Q.get(e);if(t==="objectStoreNames")return e.objectStoreNames||Me.get(e);if(t==="store")return n.objectStoreNames[1]?void 0:n.objectStore(n.objectStoreNames[0])}return g(e[t])},set(e,t,n){return e[t]=n,!0},has(e,t){return e instanceof IDBTransaction&&(t==="done"||t==="store")?!0:t in e}};function Be(e){X=e(X)}function Ft(e){return e===IDBDatabase.prototype.transaction&&!("objectStoreNames"in IDBTransaction.prototype)?function(t,...n){let r=e.call(F(this),t,...n);return Me.set(r,t.sort?t.sort():[t]),g(r)}:Pt().includes(e)?function(...t){return e.apply(F(this),t),g(Ne.get(this))}:function(...t){return g(e.apply(F(this),t))}}function Ht(e){return typeof e=="function"?Ft(e):(e instanceof IDBTransaction&&$t(e),Rt(e,Lt())?new Proxy(e,X):e)}function g(e){if(e instanceof IDBRequest)return jt(e);if(Y.has(e))return Y.get(e);let t=Ht(e);return t!==e&&(Y.set(e,t),Z.set(t,e)),t}var F=e=>Z.get(e);function v(e,t,{blocked:n,upgrade:r,blocking:i,terminated:o}={}){let s=indexedDB.open(e,t),a=g(s);return r&&s.addEventListener("upgradeneeded",u=>{r(g(s.result),u.oldVersion,u.newVersion,g(s.transaction))}),n&&s.addEventListener("blocked",()=>n()),a.then(u=>{o&&u.addEventListener("close",()=>o()),i&&u.addEventListener("versionchange",()=>i())}).catch(()=>{}),a}function H(e,{blocked:t}={}){let n=indexedDB.deleteDatabase(e);return t&&n.addEventListener("blocked",()=>t()),g(n).then(()=>{})}var Vt=["get","getKey","getAll","getAllKeys","count"],Ut=["put","add","delete","clear"],ee=new Map;function Re(e,t){if(!(e instanceof IDBDatabase&&!(t in e)&&typeof t=="string"))return;if(ee.get(t))return ee.get(t);let n=t.replace(/FromIndex$/,""),r=t!==n,i=Ut.includes(n);if(!(n in(r?IDBIndex:IDBObjectStore).prototype)||!(i||Vt.includes(n)))return;let o=async function(s,...a){let u=this.transaction(s,i?"readwrite":"readonly"),f=u.store;return r&&(f=f.index(a.shift())),(await Promise.all([f[n](...a),i&&u.done]))[0]};return ee.set(t,o),o}Be(e=>({...e,get:(t,n,r)=>Re(t,n)||e.get(t,n,r),has:(t,n)=>!!Re(t,n)||e.has(t,n)}));var ne=class{constructor(t){this.container=t}getPlatformInfoString(){return this.container.getProviders().map(n=>{if(zt(n)){let r=n.getImmediate();return`${r.library}/${r.version}`}else return null}).filter(n=>n).join(" ")}};function zt(e){let t=e.getComponent();return t?.type==="VERSION"}var re="@firebase/app",Le="0.7.33";var E=new $("@firebase/app"),Kt="@firebase/app-compat",Wt="@firebase/analytics-compat",qt="@firebase/analytics",Gt="@firebase/app-check-compat",Jt="@firebase/app-check",Yt="@firebase/auth",Qt="@firebase/auth-compat",Xt="@firebase/database",Zt="@firebase/database-compat",en="@firebase/functions",tn="@firebase/functions-compat",nn="@firebase/installations",rn="@firebase/installations-compat",on="@firebase/messaging",sn="@firebase/messaging-compat",an="@firebase/performance",cn="@firebase/performance-compat",un="@firebase/remote-config",fn="@firebase/remote-config-compat",ln="@firebase/storage",dn="@firebase/storage-compat",hn="@firebase/firestore",pn="@firebase/firestore-compat",gn="firebase";var Fe="[DEFAULT]",mn={[re]:"fire-core",[Kt]:"fire-core-compat",[qt]:"fire-analytics",[Wt]:"fire-analytics-compat",[Jt]:"fire-app-check",[Gt]:"fire-app-check-compat",[Yt]:"fire-auth",[Qt]:"fire-auth-compat",[Xt]:"fire-rtdb",[Zt]:"fire-rtdb-compat",[en]:"fire-fn",[tn]:"fire-fn-compat",[nn]:"fire-iid",[rn]:"fire-iid-compat",[on]:"fire-fcm",[sn]:"fire-fcm-compat",[an]:"fire-perf",[cn]:"fire-perf-compat",[un]:"fire-rc",[fn]:"fire-rc-compat",[ln]:"fire-gcs",[dn]:"fire-gcs-compat",[hn]:"fire-fst",[pn]:"fire-fst-compat","fire-js":"fire-js",[gn]:"fire-js-all"};var V=new Map,ie=new Map;function bn(e,t){try{e.container.addComponent(t)}catch(n){E.debug(`Component ${t.name} failed to register with FirebaseApp ${e.name}`,n)}}function y(e){let t=e.name;if(ie.has(t))return E.debug(`There were multiple attempts to register component ${t}.`),!1;ie.set(t,e);for(let n of V.values())bn(n,e);return!0}function O(e,t){let n=e.container.getProvider("heartbeat").getImmediate({optional:!0});return n&&n.triggerHeartbeat(),e.container.getProvider(t)}var wn={["no-app"]:"No Firebase App '{$appName}' has been created - call Firebase App.initializeApp()",["bad-app-name"]:"Illegal App name: '{$appName}",["duplicate-app"]:"Firebase App named '{$appName}' already exists with different options or config",["app-deleted"]:"Firebase App named '{$appName}' already deleted",["invalid-app-argument"]:"firebase.{$appName}() takes either no argument or a Firebase App instance.",["invalid-log-argument"]:"First argument to `onLog` must be null or a function.",["idb-open"]:"Error thrown when opening IndexedDB. Original error: {$originalErrorMessage}.",["idb-get"]:"Error thrown when reading from IndexedDB. Original error: {$originalErrorMessage}.",["idb-set"]:"Error thrown when writing to IndexedDB. Original error: {$originalErrorMessage}.",["idb-delete"]:"Error thrown when deleting from IndexedDB. Original error: {$originalErrorMessage}."},I=new m("app","Firebase",wn);var oe=class{constructor(t,n,r){this._isDeleted=!1,this._options=Object.assign({},t),this._config=Object.assign({},n),this._name=n.name,this._automaticDataCollectionEnabled=n.automaticDataCollectionEnabled,this._container=r,this.container.addComponent(new d("app",()=>this,"PUBLIC"))}get automaticDataCollectionEnabled(){return this.checkDestroyed(),this._automaticDataCollectionEnabled}set automaticDataCollectionEnabled(t){this.checkDestroyed(),this._automaticDataCollectionEnabled=t}get name(){return this.checkDestroyed(),this._name}get options(){return this.checkDestroyed(),this._options}get config(){return this.checkDestroyed(),this._config}get container(){return this._container}get isDeleted(){return this._isDeleted}set isDeleted(t){this._isDeleted=t}checkDestroyed(){if(this.isDeleted)throw I.create("app-deleted",{appName:this._name})}};function He(e,t={}){typeof t!="object"&&(t={name:t});let n=Object.assign({name:Fe,automaticDataCollectionEnabled:!1},t),r=n.name;if(typeof r!="string"||!r)throw I.create("bad-app-name",{appName:String(r)});let i=V.get(r);if(i){if(L(e,i.options)&&L(n,i.config))return i;throw I.create("duplicate-app",{appName:r})}let o=new j(r);for(let a of ie.values())o.addComponent(a);let s=new oe(e,n,o);return V.set(r,s),s}function ce(e=Fe){let t=V.get(e);if(!t)throw I.create("no-app",{appName:e});return t}function w(e,t,n){var r;let i=(r=mn[e])!==null&&r!==void 0?r:e;n&&(i+=`-${n}`);let o=i.match(/\s|\//),s=t.match(/\s|\//);if(o||s){let a=[`Unable to register library "${i}" with version "${t}":`];o&&a.push(`library name "${i}" contains illegal characters (whitespace or "/")`),o&&s&&a.push("and"),s&&a.push(`version name "${t}" contains illegal characters (whitespace or "/")`),E.warn(a.join(" "));return}y(new d(`${i}-version`,()=>({library:i,version:t}),"VERSION"))}var yn="firebase-heartbeat-database",_n=1,k="firebase-heartbeat-store",te=null;function Ve(){return te||(te=v(yn,_n,{upgrade:(e,t)=>{switch(t){case 0:e.createObjectStore(k)}}}).catch(e=>{throw I.create("idb-open",{originalErrorMessage:e.message})})),te}async function vn(e){var t;try{return(await Ve()).transaction(k).objectStore(k).get(Ue(e))}catch(n){if(n instanceof p)E.warn(n.message);else{let r=I.create("idb-get",{originalErrorMessage:(t=n)===null||t===void 0?void 0:t.message});E.warn(r.message)}}}async function Pe(e,t){var n;try{let i=(await Ve()).transaction(k,"readwrite");return await i.objectStore(k).put(t,Ue(e)),i.done}catch(r){if(r instanceof p)E.warn(r.message);else{let i=I.create("idb-set",{originalErrorMessage:(n=r)===null||n===void 0?void 0:n.message});E.warn(i.message)}}}function Ue(e){return`${e.name}!${e.options.appId}`}var En=1024,In=30*24*60*60*1e3,se=class{constructor(t){this.container=t,this._heartbeatsCache=null;let n=this.container.getProvider("app").getImmediate();this._storage=new ae(n),this._heartbeatsCachePromise=this._storage.read().then(r=>(this._heartbeatsCache=r,r))}async triggerHeartbeat(){let n=this.container.getProvider("platform-logger").getImmediate().getPlatformInfoString(),r=je();if(this._heartbeatsCache===null&&(this._heartbeatsCache=await this._heartbeatsCachePromise),!(this._heartbeatsCache.lastSentHeartbeatDate===r||this._heartbeatsCache.heartbeats.some(i=>i.date===r)))return this._heartbeatsCache.heartbeats.push({date:r,agent:n}),this._heartbeatsCache.heartbeats=this._heartbeatsCache.heartbeats.filter(i=>{let o=new Date(i.date).valueOf();return Date.now()-o<=In}),this._storage.overwrite(this._heartbeatsCache)}async getHeartbeatsHeader(){if(this._heartbeatsCache===null&&await this._heartbeatsCachePromise,this._heartbeatsCache===null||this._heartbeatsCache.heartbeats.length===0)return"";let t=je(),{heartbeatsToSend:n,unsentEntries:r}=Sn(this._heartbeatsCache.heartbeats),i=G(JSON.stringify({version:2,heartbeats:n}));return this._heartbeatsCache.lastSentHeartbeatDate=t,r.length>0?(this._heartbeatsCache.heartbeats=r,await this._storage.overwrite(this._heartbeatsCache)):(this._heartbeatsCache.heartbeats=[],this._storage.overwrite(this._heartbeatsCache)),i}};function je(){return new Date().toISOString().substring(0,10)}function Sn(e,t=En){let n=[],r=e.slice();for(let i of e){let o=n.find(s=>s.agent===i.agent);if(o){if(o.dates.push(i.date),$e(n)>t){o.dates.pop();break}}else if(n.push({agent:i.agent,dates:[i.date]}),$e(n)>t){n.pop();break}r=r.slice(1)}return{heartbeatsToSend:n,unsentEntries:r}}var ae=class{constructor(t){this.app=t,this._canUseIndexedDBPromise=this.runIndexedDBEnvironmentCheck()}async runIndexedDBEnvironmentCheck(){return B()?R().then(()=>!0).catch(()=>!1):!1}async read(){return await this._canUseIndexedDBPromise?await vn(this.app)||{heartbeats:[]}:{heartbeats:[]}}async overwrite(t){var n;if(await this._canUseIndexedDBPromise){let i=await this.read();return Pe(this.app,{lastSentHeartbeatDate:(n=t.lastSentHeartbeatDate)!==null&&n!==void 0?n:i.lastSentHeartbeatDate,heartbeats:t.heartbeats})}else return}async add(t){var n;if(await this._canUseIndexedDBPromise){let i=await this.read();return Pe(this.app,{lastSentHeartbeatDate:(n=t.lastSentHeartbeatDate)!==null&&n!==void 0?n:i.lastSentHeartbeatDate,heartbeats:[...i.heartbeats,...t.heartbeats]})}else return}};function $e(e){return G(JSON.stringify({version:2,heartbeats:e})).length}function An(e){y(new d("platform-logger",t=>new ne(t),"PRIVATE")),y(new d("heartbeat",t=>new se(t),"PRIVATE")),w(re,Le,e),w(re,Le,"esm2017"),w("fire-js","")}An("");var Tn="firebase",Dn="9.10.0";w(Tn,Dn,"app");var We="@firebase/installations",de="0.5.12";var qe=1e4,Ge=`w:${de}`,Je="FIS_v2",Cn="https://firebaseinstallations.googleapis.com/v1",kn=60*60*1e3,On="installations",xn="Installations";var Nn={["missing-app-config-values"]:'Missing App configuration value: "{$valueName}"',["not-registered"]:"Firebase Installation is not registered.",["installation-not-found"]:"Firebase Installation not found.",["request-failed"]:'{$requestName} request failed with error "{$serverCode} {$serverStatus}: {$serverMessage}"',["app-offline"]:"Could not process request. Application offline.",["delete-pending-registration"]:"Can't delete installation while there is a pending registration request."},A=new m(On,xn,Nn);function Ye(e){return e instanceof p&&e.code.includes("request-failed")}function Qe({projectId:e}){return`${Cn}/projects/${e}/installations`}function Xe(e){return{token:e.token,requestStatus:2,expiresIn:Bn(e.expiresIn),creationTime:Date.now()}}async function Ze(e,t){let r=(await t.json()).error;return A.create("request-failed",{requestName:e,serverCode:r.code,serverMessage:r.message,serverStatus:r.status})}function et({apiKey:e}){return new Headers({"Content-Type":"application/json",Accept:"application/json","x-goog-api-key":e})}function Mn(e,{refreshToken:t}){let n=et(e);return n.append("Authorization",Rn(t)),n}async function tt(e){let t=await e();return t.status>=500&&t.status<600?e():t}function Bn(e){return Number(e.replace("s","000"))}function Rn(e){return`${Je} ${e}`}async function Ln({appConfig:e,heartbeatServiceProvider:t},{fid:n}){let r=Qe(e),i=et(e),o=t.getImmediate({optional:!0});if(o){let f=await o.getHeartbeatsHeader();f&&i.append("x-firebase-client",f)}let s={fid:n,authVersion:Je,appId:e.appId,sdkVersion:Ge},a={method:"POST",headers:i,body:JSON.stringify(s)},u=await tt(()=>fetch(r,a));if(u.ok){let f=await u.json();return{fid:f.fid||n,registrationStatus:2,refreshToken:f.refreshToken,authToken:Xe(f.authToken)}}else throw await Ze("Create Installation",u)}function nt(e){return new Promise(t=>{setTimeout(t,e)})}function Pn(e){return btoa(String.fromCharCode(...e)).replace(/\+/g,"-").replace(/\//g,"_")}var jn=/^[cdef][\w-]{21}$/,le="";function $n(){try{let e=new Uint8Array(17);(self.crypto||self.msCrypto).getRandomValues(e),e[0]=112+e[0]%16;let n=Fn(e);return jn.test(n)?n:le}catch{return le}}function Fn(e){return Pn(e).substr(0,22)}function z(e){return`${e.appName}!${e.appId}`}var rt=new Map;function it(e,t){let n=z(e);ot(n,t),Hn(n,t)}function ot(e,t){let n=rt.get(e);if(!!n)for(let r of n)r(t)}function Hn(e,t){let n=Vn();n&&n.postMessage({key:e,fid:t}),Un()}var S=null;function Vn(){return!S&&"BroadcastChannel"in self&&(S=new BroadcastChannel("[Firebase] FID Change"),S.onmessage=e=>{ot(e.data.key,e.data.fid)}),S}function Un(){rt.size===0&&S&&(S.close(),S=null)}var zn="firebase-installations-database",Kn=1,T="firebase-installations-store",ue=null;function he(){return ue||(ue=v(zn,Kn,{upgrade:(e,t)=>{switch(t){case 0:e.createObjectStore(T)}}})),ue}async function U(e,t){let n=z(e),i=(await he()).transaction(T,"readwrite"),o=i.objectStore(T),s=await o.get(n);return await o.put(t,n),await i.done,(!s||s.fid!==t.fid)&&it(e,t.fid),t}async function st(e){let t=z(e),r=(await he()).transaction(T,"readwrite");await r.objectStore(T).delete(t),await r.done}async function K(e,t){let n=z(e),i=(await he()).transaction(T,"readwrite"),o=i.objectStore(T),s=await o.get(n),a=t(s);return a===void 0?await o.delete(n):await o.put(a,n),await i.done,a&&(!s||s.fid!==a.fid)&&it(e,a.fid),a}async function pe(e){let t,n=await K(e.appConfig,r=>{let i=Wn(r),o=qn(e,i);return t=o.registrationPromise,o.installationEntry});return n.fid===le?{installationEntry:await t}:{installationEntry:n,registrationPromise:t}}function Wn(e){let t=e||{fid:$n(),registrationStatus:0};return at(t)}function qn(e,t){if(t.registrationStatus===0){if(!navigator.onLine){let i=Promise.reject(A.create("app-offline"));return{installationEntry:t,registrationPromise:i}}let n={fid:t.fid,registrationStatus:1,registrationTime:Date.now()},r=Gn(e,n);return{installationEntry:n,registrationPromise:r}}else return t.registrationStatus===1?{installationEntry:t,registrationPromise:Jn(e)}:{installationEntry:t}}async function Gn(e,t){try{let n=await Ln(e,t);return U(e.appConfig,n)}catch(n){throw Ye(n)&&n.customData.serverCode===409?await st(e.appConfig):await U(e.appConfig,{fid:t.fid,registrationStatus:0}),n}}async function Jn(e){let t=await ze(e.appConfig);for(;t.registrationStatus===1;)await nt(100),t=await ze(e.appConfig);if(t.registrationStatus===0){let{installationEntry:n,registrationPromise:r}=await pe(e);return r||n}return t}function ze(e){return K(e,t=>{if(!t)throw A.create("installation-not-found");return at(t)})}function at(e){return Yn(e)?{fid:e.fid,registrationStatus:0}:e}function Yn(e){return e.registrationStatus===1&&e.registrationTime+qefetch(r,a));if(u.ok){let f=await u.json();return Xe(f)}else throw await Ze("Generate Auth Token",u)}function Xn(e,{fid:t}){return`${Qe(e)}/${t}/authTokens:generate`}async function ge(e,t=!1){let n,r=await K(e.appConfig,o=>{if(!ct(o))throw A.create("not-registered");let s=o.authToken;if(!t&&tr(s))return o;if(s.requestStatus===1)return n=Zn(e,t),o;{if(!navigator.onLine)throw A.create("app-offline");let a=rr(o);return n=er(e,a),a}});return n?await n:r.authToken}async function Zn(e,t){let n=await Ke(e.appConfig);for(;n.authToken.requestStatus===1;)await nt(100),n=await Ke(e.appConfig);let r=n.authToken;return r.requestStatus===0?ge(e,t):r}function Ke(e){return K(e,t=>{if(!ct(t))throw A.create("not-registered");let n=t.authToken;return ir(n)?Object.assign(Object.assign({},t),{authToken:{requestStatus:0}}):t})}async function er(e,t){try{let n=await Qn(e,t),r=Object.assign(Object.assign({},t),{authToken:n});return await U(e.appConfig,r),n}catch(n){if(Ye(n)&&(n.customData.serverCode===401||n.customData.serverCode===404))await st(e.appConfig);else{let r=Object.assign(Object.assign({},t),{authToken:{requestStatus:0}});await U(e.appConfig,r)}throw n}}function ct(e){return e!==void 0&&e.registrationStatus===2}function tr(e){return e.requestStatus===2&&!nr(e)}function nr(e){let t=Date.now();return t{let t=e.getProvider("app").getImmediate(),n=cr(t),r=O(t,"heartbeat");return{app:t,appConfig:n,heartbeatServiceProvider:r,_delete:()=>Promise.resolve()}},lr=e=>{let t=e.getProvider("app").getImmediate(),n=O(t,ut).getImmediate();return{getId:()=>or(n),getToken:i=>sr(n,i)}};function dr(){y(new d(ut,fr,"PUBLIC")),y(new d(ur,lr,"PRIVATE"))}dr();w(We,de);w(We,de,"esm2017");var dt="BDOU99-h67HcA6JeFXHbSNMu7e2yNNu3RzoMj8TM4W88jITfq7ZmPvIM1Iv-4_l2LxQcYwhqby2xGpWwzjfAnG4",hr="https://fcmregistrations.googleapis.com/v1",ht="FCM_MSG",pr="google.c.a.c_id",gr=3,mr=1,W;(function(e){e[e.DATA_MESSAGE=1]="DATA_MESSAGE",e[e.DISPLAY_NOTIFICATION=3]="DISPLAY_NOTIFICATION"})(W||(W={}));var q;(function(e){e.PUSH_RECEIVED="push-received",e.NOTIFICATION_CLICKED="notification-clicked"})(q||(q={}));function b(e){let t=new Uint8Array(e);return btoa(String.fromCharCode(...t)).replace(/=/g,"").replace(/\+/g,"-").replace(/\//g,"_")}function br(e){let t="=".repeat((4-e.length%4)%4),n=(e+t).replace(/\-/g,"+").replace(/_/g,"/"),r=atob(n),i=new Uint8Array(r.length);for(let o=0;oo.name).includes(me))return null;let t=null;return(await v(me,wr,{upgrade:async(r,i,o,s)=>{var a;if(i<2||!r.objectStoreNames.contains(ft))return;let u=s.objectStore(ft),f=await u.index("fcmSenderId").get(e);if(await u.clear(),!!f){if(i===2){let c=f;if(!c.auth||!c.p256dh||!c.endpoint)return;t={token:c.fcmToken,createTime:(a=c.createTime)!==null&&a!==void 0?a:Date.now(),subscriptionOptions:{auth:c.auth,p256dh:c.p256dh,endpoint:c.endpoint,swScope:c.swScope,vapidKey:typeof c.vapidKey=="string"?c.vapidKey:b(c.vapidKey)}}}else if(i===3){let c=f;t={token:c.fcmToken,createTime:c.createTime,subscriptionOptions:{auth:b(c.auth),p256dh:b(c.p256dh),endpoint:c.endpoint,swScope:c.swScope,vapidKey:b(c.vapidKey)}}}else if(i===4){let c=f;t={token:c.fcmToken,createTime:c.createTime,subscriptionOptions:{auth:b(c.auth),p256dh:b(c.p256dh),endpoint:c.endpoint,swScope:c.swScope,vapidKey:b(c.vapidKey)}}}}}})).close(),await H(me),await H("fcm_vapid_details_db"),await H("undefined"),_r(t)?t:null}function _r(e){if(!e||!e.subscriptionOptions)return!1;let{subscriptionOptions:t}=e;return typeof e.createTime=="number"&&e.createTime>0&&typeof e.token=="string"&&e.token.length>0&&typeof t.auth=="string"&&t.auth.length>0&&typeof t.p256dh=="string"&&t.p256dh.length>0&&typeof t.endpoint=="string"&&t.endpoint.length>0&&typeof t.swScope=="string"&&t.swScope.length>0&&typeof t.vapidKey=="string"&&t.vapidKey.length>0}var vr="firebase-messaging-database",Er=1,D="firebase-messaging-store",be=null;function ve(){return be||(be=v(vr,Er,{upgrade:(e,t)=>{switch(t){case 0:e.createObjectStore(D)}}})),be}async function Ee(e){let t=Se(e),r=await(await ve()).transaction(D).objectStore(D).get(t);if(r)return r;{let i=await yr(e.appConfig.senderId);if(i)return await Ie(e,i),i}}async function Ie(e,t){let n=Se(e),i=(await ve()).transaction(D,"readwrite");return await i.objectStore(D).put(t,n),await i.done,t}async function Ir(e){let t=Se(e),r=(await ve()).transaction(D,"readwrite");await r.objectStore(D).delete(t),await r.done}function Se({appConfig:e}){return e.appId}var Sr={["missing-app-config-values"]:'Missing App configuration value: "{$valueName}"',["only-available-in-window"]:"This method is available in a Window context.",["only-available-in-sw"]:"This method is available in a service worker context.",["permission-default"]:"The notification permission was not granted and dismissed instead.",["permission-blocked"]:"The notification permission was not granted and blocked instead.",["unsupported-browser"]:"This browser doesn't support the API's required to use the Firebase SDK.",["indexed-db-unsupported"]:"This browser doesn't support indexedDb.open() (ex. Safari iFrame, Firefox Private Browsing, etc)",["failed-service-worker-registration"]:"We are unable to register the default service worker. {$browserErrorMessage}",["token-subscribe-failed"]:"A problem occurred while subscribing the user to FCM: {$errorInfo}",["token-subscribe-no-token"]:"FCM returned no token when subscribing the user to push.",["token-unsubscribe-failed"]:"A problem occurred while unsubscribing the user from FCM: {$errorInfo}",["token-update-failed"]:"A problem occurred while updating the user from FCM: {$errorInfo}",["token-update-no-token"]:"FCM returned no token when updating the user to push.",["use-sw-after-get-token"]:"The useServiceWorker() method may only be called once and must be called before calling getToken() to ensure your service worker is used.",["invalid-sw-registration"]:"The input to useServiceWorker() must be a ServiceWorkerRegistration.",["invalid-bg-handler"]:"The input to setBackgroundMessageHandler() must be a function.",["invalid-vapid-key"]:"The public VAPID key must be a string.",["use-vapid-key-after-get-token"]:"The usePublicVapidKey() method may only be called once and must be called before calling getToken() to ensure your VAPID key is used."},h=new m("messaging","Messaging",Sr);async function Ar(e,t){var n;let r=await Te(e),i=gt(t),o={method:"POST",headers:r,body:JSON.stringify(i)},s;try{s=await(await fetch(Ae(e.appConfig),o)).json()}catch(a){throw h.create("token-subscribe-failed",{errorInfo:(n=a)===null||n===void 0?void 0:n.toString()})}if(s.error){let a=s.error.message;throw h.create("token-subscribe-failed",{errorInfo:a})}if(!s.token)throw h.create("token-subscribe-no-token");return s.token}async function Tr(e,t){var n;let r=await Te(e),i=gt(t.subscriptionOptions),o={method:"PATCH",headers:r,body:JSON.stringify(i)},s;try{s=await(await fetch(`${Ae(e.appConfig)}/${t.token}`,o)).json()}catch(a){throw h.create("token-update-failed",{errorInfo:(n=a)===null||n===void 0?void 0:n.toString()})}if(s.error){let a=s.error.message;throw h.create("token-update-failed",{errorInfo:a})}if(!s.token)throw h.create("token-update-no-token");return s.token}async function pt(e,t){var n;let r=await Te(e),i={method:"DELETE",headers:r};try{let s=await(await fetch(`${Ae(e.appConfig)}/${t}`,i)).json();if(s.error){let a=s.error.message;throw h.create("token-unsubscribe-failed",{errorInfo:a})}}catch(o){throw h.create("token-unsubscribe-failed",{errorInfo:(n=o)===null||n===void 0?void 0:n.toString()})}}function Ae({projectId:e}){return`${hr}/projects/${e}/registrations`}async function Te({appConfig:e,installations:t}){let n=await t.getToken();return new Headers({"Content-Type":"application/json",Accept:"application/json","x-goog-api-key":e.apiKey,"x-goog-firebase-installations-auth":`FIS ${n}`})}function gt({p256dh:e,auth:t,endpoint:n,vapidKey:r}){let i={web:{endpoint:n,auth:t,p256dh:e}};return r!==dt&&(i.web.applicationPubKey=r),i}var Dr=7*24*60*60*1e3;async function Cr(e){let t=await Or(e.swRegistration,e.vapidKey),n={vapidKey:e.vapidKey,swScope:e.swRegistration.scope,endpoint:t.endpoint,auth:b(t.getKey("auth")),p256dh:b(t.getKey("p256dh"))},r=await Ee(e.firebaseDependencies);if(r){if(xr(r.subscriptionOptions,n))return Date.now()>=r.createTime+Dr?kr(e,{token:r.token,createTime:Date.now(),subscriptionOptions:n}):r.token;try{await pt(e.firebaseDependencies,r.token)}catch(i){console.warn(i)}return lt(e.firebaseDependencies,n)}else return lt(e.firebaseDependencies,n)}async function ye(e){let t=await Ee(e.firebaseDependencies);t&&(await pt(e.firebaseDependencies,t.token),await Ir(e.firebaseDependencies));let n=await e.swRegistration.pushManager.getSubscription();return n?n.unsubscribe():!0}async function kr(e,t){try{let n=await Tr(e.firebaseDependencies,t),r=Object.assign(Object.assign({},t),{token:n,createTime:Date.now()});return await Ie(e.firebaseDependencies,r),n}catch(n){throw await ye(e),n}}async function lt(e,t){let r={token:await Ar(e,t),createTime:Date.now(),subscriptionOptions:t};return await Ie(e,r),r.token}async function Or(e,t){let n=await e.pushManager.getSubscription();return n||e.pushManager.subscribe({userVisibleOnly:!0,applicationServerKey:br(t)})}function xr(e,t){let n=t.vapidKey===e.vapidKey,r=t.endpoint===e.endpoint,i=t.auth===e.auth,o=t.p256dh===e.p256dh;return n&&r&&i&&o}function Nr(e){let t={from:e.from,collapseKey:e.collapse_key,messageId:e.fcmMessageId};return Mr(t,e),Br(t,e),Rr(t,e),t}function Mr(e,t){if(!t.notification)return;e.notification={};let n=t.notification.title;n&&(e.notification.title=n);let r=t.notification.body;r&&(e.notification.body=r);let i=t.notification.image;i&&(e.notification.image=i)}function Br(e,t){!t.data||(e.data=t.data)}function Rr(e,t){var n,r,i,o,s;if(!t.fcmOptions&&!(!((n=t.notification)===null||n===void 0)&&n.click_action))return;e.fcmOptions={};let a=(i=(r=t.fcmOptions)===null||r===void 0?void 0:r.link)!==null&&i!==void 0?i:(o=t.notification)===null||o===void 0?void 0:o.click_action;a&&(e.fcmOptions.link=a);let u=(s=t.fcmOptions)===null||s===void 0?void 0:s.analytics_label;u&&(e.fcmOptions.analyticsLabel=u)}function Lr(e){return typeof e=="object"&&!!e&&pr in e}function Pr(e){return new Promise(t=>{setTimeout(t,e)})}mt("hts/frbslgigp.ogepscmv/ieo/eaylg","tp:/ieaeogn-agolai.o/1frlglgc/o");mt("AzSCbw63g1R0nCw85jG8","Iaya3yLKwmgvh7cF0q4");async function jr(e,t){let n=$r(t,await e.firebaseDependencies.installations.getId());Fr(e,n)}function $r(e,t){var n,r;let i={};return e.from&&(i.project_number=e.from),e.fcmMessageId&&(i.message_id=e.fcmMessageId),i.instance_id=t,e.notification?i.message_type=W.DISPLAY_NOTIFICATION.toString():i.message_type=W.DATA_MESSAGE.toString(),i.sdk_platform=gr.toString(),i.package_name=self.origin.replace(/(^\w+:|^)\/\//,""),e.collapse_key&&(i.collapse_key=e.collapse_key),i.event=mr.toString(),!((n=e.fcmOptions)===null||n===void 0)&&n.analytics_label&&(i.analytics_label=(r=e.fcmOptions)===null||r===void 0?void 0:r.analytics_label),i}function Fr(e,t){let n={};n.event_time_ms=Math.floor(Date.now()).toString(),n.source_extension_json_proto3=JSON.stringify(t),e.logEvents.push(n)}function mt(e,t){let n=[];for(let r=0;rt.visibilityState==="visible"&&!t.url.startsWith("chrome-extension://"))}function Gr(e,t){t.isFirebaseMessaging=!0,t.messageType=q.PUSH_RECEIVED;for(let n of e)n.postMessage(t)}function bt(){return self.clients.matchAll({type:"window",includeUncontrolled:!0})}function Jr(e){var t;let{actions:n}=e,{maxActions:r}=Notification;return n&&r&&n.length>r&&console.warn(`This browser only supports ${r} actions. The remaining actions will not be displayed.`),self.registration.showNotification((t=e.title)!==null&&t!==void 0?t:"",e)}function Yr(e){var t,n,r;let i=(n=(t=e.fcmOptions)===null||t===void 0?void 0:t.link)!==null&&n!==void 0?n:(r=e.notification)===null||r===void 0?void 0:r.click_action;return i||(Lr(e.data)?self.location.origin:null)}function Qr(e){if(!e||!e.options)throw we("App Configuration Object");if(!e.name)throw we("App Name");let t=["projectId","apiKey","appId","messagingSenderId"],{options:n}=e;for(let r of t)if(!n[r])throw we(r);return{appName:e.name,projectId:n.projectId,apiKey:n.apiKey,appId:n.appId,senderId:n.messagingSenderId}}function we(e){return h.create("missing-app-config-values",{valueName:e})}var _e=class{constructor(t,n,r){this.deliveryMetricsExportedToBigQueryEnabled=!1,this.onBackgroundMessageHandler=null,this.onMessageHandler=null,this.logEvents=[],this.isLogServiceStarted=!1;let i=Qr(t);this.firebaseDependencies={app:t,appConfig:i,installations:n,analyticsProvider:r}}_delete(){return Promise.resolve()}};var Xr=e=>{let t=new _e(e.getProvider("app").getImmediate(),e.getProvider("installations-internal").getImmediate(),e.getProvider("analytics-internal"));return self.addEventListener("push",n=>{n.waitUntil(Vr(n,t))}),self.addEventListener("pushsubscriptionchange",n=>{n.waitUntil(Hr(n,t))}),self.addEventListener("notificationclick",n=>{n.waitUntil(Ur(n))}),t};function Zr(){y(new d("messaging-sw",Xr,"PUBLIC"))}async function De(){return B()&&await R()&&"PushManager"in self&&"Notification"in self&&ServiceWorkerRegistration.prototype.hasOwnProperty("showNotification")&&PushSubscription.prototype.hasOwnProperty("getKey")}function ei(e,t){if(self.document!==void 0)throw h.create("only-available-in-sw");return e.onBackgroundMessageHandler=t,()=>{e.onBackgroundMessageHandler=null}}function ti(e,t){e.deliveryMetricsExportedToBigQueryEnabled=t}function wt(e=ce()){return De().then(t=>{if(!t)throw h.create("unsupported-browser")},t=>{throw h.create("indexed-db-unsupported")}),O(P(e),"messaging-sw").getImmediate()}function yt(e,t){return e=P(e),ei(e,t)}function _t(e,t){return e=P(e),ti(e,t)}Zr();self.addEventListener("install",e=>{console.log(self),console.log(e)});var ni=He({apiKey:"AIzaSyAgUhHU8wSJgO5MVNy95tMT07NEjzMOfz0",authDomain:"react-native-firebase-testing.firebaseapp.com",databaseURL:"https://react-native-firebase-testing.firebaseio.com",projectId:"react-native-firebase-testing",storageBucket:"react-native-firebase-testing.appspot.com",messagingSenderId:"448618578101",appId:"1:448618578101:web:ecaffe2bc4511738"});De().then(e=>{if(e){let t=wt(ni);_t(t,!0),console.log("experimental working"),yt(t,({notification:n})=>{let{title:r,body:i,image:o}=n??{};!r||self.registration.showNotification(r,{body:i,icon:o||"/assets/icons/icon-72x72.png"})})}}); -/** - * @license - * Copyright 2017 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. - */ -/** - * @license - * Copyright 2018 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. - */ -/** - * @license - * Copyright 2019 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. - */ -/** - * @license - * Copyright 2020 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. - */ -/** - * @license - * Copyright 2021 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. - */ -/** - * @license - * Copyright 2022 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. - */ -//# sourceMappingURL=firebase-messaging-sw.js.map +importScripts("https://www.gstatic.com/firebasejs/9.10.0/firebase-app-compat.js"); +importScripts("https://www.gstatic.com/firebasejs/9.10.0/firebase-messaging-compat.js"); + +firebase.initializeApp({ + apiKey: "AIzaSyAgUhHU8wSJgO5MVNy95tMT07NEjzMOfz0", + authDomain: "react-native-firebase-testing.firebaseapp.com", + databaseURL: "https://react-native-firebase-testing.firebaseio.com", + projectId: "react-native-firebase-testing", + storageBucket: "react-native-firebase-testing.appspot.com", + messagingSenderId: "448618578101", + appId: "1:448618578101:web:ecaffe2bc4511738", +}); +// Necessary to receive background messages: +const messaging = firebase.messaging(); + +// Optional: +messaging.onBackgroundMessage((m) => { + console.log("onBackgroundMessage", m); +}); diff --git a/packages/firebase_messaging/firebase_messaging/example/web/firebase-messaging-sw.js.map b/packages/firebase_messaging/firebase_messaging/example/web/firebase-messaging-sw.js.map deleted file mode 100644 index 094a11115c4e..000000000000 --- a/packages/firebase_messaging/firebase_messaging/example/web/firebase-messaging-sw.js.map +++ /dev/null @@ -1,7 +0,0 @@ -{ - "version": 3, - "sources": ["../bundled-service-worker/node_modules/@firebase/util/src/constants.ts", "../bundled-service-worker/node_modules/@firebase/util/src/assert.ts", "../bundled-service-worker/node_modules/@firebase/util/src/crypt.ts", "../bundled-service-worker/node_modules/@firebase/util/src/deepCopy.ts", "../bundled-service-worker/node_modules/@firebase/util/src/deferred.ts", "../bundled-service-worker/node_modules/@firebase/util/src/emulator.ts", "../bundled-service-worker/node_modules/@firebase/util/src/environment.ts", "../bundled-service-worker/node_modules/@firebase/util/src/errors.ts", "../bundled-service-worker/node_modules/@firebase/util/src/json.ts", "../bundled-service-worker/node_modules/@firebase/util/src/jwt.ts", "../bundled-service-worker/node_modules/@firebase/util/src/obj.ts", "../bundled-service-worker/node_modules/@firebase/util/src/promise.ts", "../bundled-service-worker/node_modules/@firebase/util/src/query.ts", "../bundled-service-worker/node_modules/@firebase/util/src/sha1.ts", "../bundled-service-worker/node_modules/@firebase/util/src/subscribe.ts", "../bundled-service-worker/node_modules/@firebase/util/src/validation.ts", "../bundled-service-worker/node_modules/@firebase/util/src/utf8.ts", "../bundled-service-worker/node_modules/@firebase/util/src/uuid.ts", "../bundled-service-worker/node_modules/@firebase/util/src/exponential_backoff.ts", "../bundled-service-worker/node_modules/@firebase/util/src/formatters.ts", "../bundled-service-worker/node_modules/@firebase/util/src/compat.ts", "../bundled-service-worker/node_modules/@firebase/component/src/component.ts", "../bundled-service-worker/node_modules/@firebase/component/src/constants.ts", "../bundled-service-worker/node_modules/@firebase/component/src/provider.ts", "../bundled-service-worker/node_modules/@firebase/component/src/component_container.ts", "../bundled-service-worker/node_modules/@firebase/logger/src/logger.ts", "../bundled-service-worker/node_modules/idb/build/wrap-idb-value.js", "../bundled-service-worker/node_modules/idb/build/index.js", "../bundled-service-worker/node_modules/@firebase/app/src/platformLoggerService.ts", "../bundled-service-worker/node_modules/@firebase/app/src/logger.ts", "../bundled-service-worker/node_modules/@firebase/app/src/constants.ts", "../bundled-service-worker/node_modules/@firebase/app/src/internal.ts", "../bundled-service-worker/node_modules/@firebase/app/src/errors.ts", "../bundled-service-worker/node_modules/@firebase/app/src/firebaseApp.ts", "../bundled-service-worker/node_modules/@firebase/app/src/api.ts", "../bundled-service-worker/node_modules/@firebase/app/src/indexeddb.ts", "../bundled-service-worker/node_modules/@firebase/app/src/heartbeatService.ts", "../bundled-service-worker/node_modules/@firebase/app/src/registerCoreComponents.ts", "../bundled-service-worker/node_modules/@firebase/app/src/index.ts", "../bundled-service-worker/node_modules/firebase/app/index.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/util/constants.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/util/errors.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/functions/common.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/functions/create-installation-request.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/util/sleep.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/helpers/buffer-to-base64-url-safe.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/helpers/generate-fid.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/util/get-key.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/helpers/fid-changed.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/helpers/idb-manager.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/helpers/get-installation-entry.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/functions/generate-auth-token-request.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/helpers/refresh-auth-token.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/api/get-id.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/api/get-token.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/functions/delete-installation-request.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/api/delete-installations.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/api/on-id-change.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/api/get-installations.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/helpers/extract-app-config.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/functions/config.ts", "../bundled-service-worker/node_modules/@firebase/installations/src/index.ts", "../bundled-service-worker/node_modules/@firebase/messaging/src/util/constants.ts", "../bundled-service-worker/node_modules/@firebase/messaging/src/interfaces/internal-message-payload.ts", "../bundled-service-worker/node_modules/@firebase/messaging/src/helpers/array-base64-translator.ts", "../bundled-service-worker/node_modules/@firebase/messaging/src/helpers/migrate-old-database.ts", "../bundled-service-worker/node_modules/@firebase/messaging/src/internals/idb-manager.ts", "../bundled-service-worker/node_modules/@firebase/messaging/src/util/errors.ts", "../bundled-service-worker/node_modules/@firebase/messaging/src/internals/requests.ts", "../bundled-service-worker/node_modules/@firebase/messaging/src/internals/token-manager.ts", "../bundled-service-worker/node_modules/@firebase/messaging/src/helpers/externalizePayload.ts", "../bundled-service-worker/node_modules/@firebase/messaging/src/helpers/is-console-message.ts", "../bundled-service-worker/node_modules/@firebase/messaging/src/helpers/sleep.ts", "../bundled-service-worker/node_modules/@firebase/messaging/src/helpers/logToFirelog.ts", "../bundled-service-worker/node_modules/@firebase/messaging/src/listeners/sw-listeners.ts", "../bundled-service-worker/node_modules/@firebase/messaging/src/helpers/extract-app-config.ts", "../bundled-service-worker/node_modules/@firebase/messaging/src/messaging-service.ts", "../bundled-service-worker/node_modules/@firebase/messaging/src/helpers/register.ts", "../bundled-service-worker/node_modules/@firebase/messaging/src/api/isSupported.ts", "../bundled-service-worker/node_modules/@firebase/messaging/src/api/onBackgroundMessage.ts", "../bundled-service-worker/node_modules/@firebase/messaging/src/api/setDeliveryMetricsExportedToBigQueryEnabled.ts", "../bundled-service-worker/node_modules/@firebase/messaging/src/api.ts", "../bundled-service-worker/node_modules/@firebase/messaging/src/index.sw.ts", "../bundled-service-worker/firebase-messaging-sw.ts"], - "sourcesContent": ["/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * @fileoverview Firebase constants. Some of these (@defines) can be overridden at compile-time.\n */\n\nexport const CONSTANTS = {\n /**\n * @define {boolean} Whether this is the client Node.js SDK.\n */\n NODE_CLIENT: false,\n /**\n * @define {boolean} Whether this is the Admin Node.js SDK.\n */\n NODE_ADMIN: false,\n\n /**\n * Firebase SDK Version\n */\n SDK_VERSION: '${JSCORE_VERSION}'\n};\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { CONSTANTS } from './constants';\n\n/**\n * Throws an error if the provided assertion is falsy\n */\nexport const assert = function (assertion: unknown, message: string): void {\n if (!assertion) {\n throw assertionError(message);\n }\n};\n\n/**\n * Returns an Error object suitable for throwing.\n */\nexport const assertionError = function (message: string): Error {\n return new Error(\n 'Firebase Database (' +\n CONSTANTS.SDK_VERSION +\n ') INTERNAL ASSERT FAILED: ' +\n message\n );\n};\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nconst stringToByteArray = function (str: string): number[] {\n // TODO(user): Use native implementations if/when available\n const out: number[] = [];\n let p = 0;\n for (let i = 0; i < str.length; i++) {\n let c = str.charCodeAt(i);\n if (c < 128) {\n out[p++] = c;\n } else if (c < 2048) {\n out[p++] = (c >> 6) | 192;\n out[p++] = (c & 63) | 128;\n } else if (\n (c & 0xfc00) === 0xd800 &&\n i + 1 < str.length &&\n (str.charCodeAt(i + 1) & 0xfc00) === 0xdc00\n ) {\n // Surrogate Pair\n c = 0x10000 + ((c & 0x03ff) << 10) + (str.charCodeAt(++i) & 0x03ff);\n out[p++] = (c >> 18) | 240;\n out[p++] = ((c >> 12) & 63) | 128;\n out[p++] = ((c >> 6) & 63) | 128;\n out[p++] = (c & 63) | 128;\n } else {\n out[p++] = (c >> 12) | 224;\n out[p++] = ((c >> 6) & 63) | 128;\n out[p++] = (c & 63) | 128;\n }\n }\n return out;\n};\n\n/**\n * Turns an array of numbers into the string given by the concatenation of the\n * characters to which the numbers correspond.\n * @param bytes Array of numbers representing characters.\n * @return Stringification of the array.\n */\nconst byteArrayToString = function (bytes: number[]): string {\n // TODO(user): Use native implementations if/when available\n const out: string[] = [];\n let pos = 0,\n c = 0;\n while (pos < bytes.length) {\n const c1 = bytes[pos++];\n if (c1 < 128) {\n out[c++] = String.fromCharCode(c1);\n } else if (c1 > 191 && c1 < 224) {\n const c2 = bytes[pos++];\n out[c++] = String.fromCharCode(((c1 & 31) << 6) | (c2 & 63));\n } else if (c1 > 239 && c1 < 365) {\n // Surrogate Pair\n const c2 = bytes[pos++];\n const c3 = bytes[pos++];\n const c4 = bytes[pos++];\n const u =\n (((c1 & 7) << 18) | ((c2 & 63) << 12) | ((c3 & 63) << 6) | (c4 & 63)) -\n 0x10000;\n out[c++] = String.fromCharCode(0xd800 + (u >> 10));\n out[c++] = String.fromCharCode(0xdc00 + (u & 1023));\n } else {\n const c2 = bytes[pos++];\n const c3 = bytes[pos++];\n out[c++] = String.fromCharCode(\n ((c1 & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)\n );\n }\n }\n return out.join('');\n};\n\ninterface Base64 {\n byteToCharMap_: { [key: number]: string } | null;\n charToByteMap_: { [key: string]: number } | null;\n byteToCharMapWebSafe_: { [key: number]: string } | null;\n charToByteMapWebSafe_: { [key: string]: number } | null;\n ENCODED_VALS_BASE: string;\n readonly ENCODED_VALS: string;\n readonly ENCODED_VALS_WEBSAFE: string;\n HAS_NATIVE_SUPPORT: boolean;\n encodeByteArray(input: number[] | Uint8Array, webSafe?: boolean): string;\n encodeString(input: string, webSafe?: boolean): string;\n decodeString(input: string, webSafe: boolean): string;\n decodeStringToByteArray(input: string, webSafe: boolean): number[];\n init_(): void;\n}\n\n// We define it as an object literal instead of a class because a class compiled down to es5 can't\n// be treeshaked. https://github.com/rollup/rollup/issues/1691\n// Static lookup maps, lazily populated by init_()\nexport const base64: Base64 = {\n /**\n * Maps bytes to characters.\n */\n byteToCharMap_: null,\n\n /**\n * Maps characters to bytes.\n */\n charToByteMap_: null,\n\n /**\n * Maps bytes to websafe characters.\n * @private\n */\n byteToCharMapWebSafe_: null,\n\n /**\n * Maps websafe characters to bytes.\n * @private\n */\n charToByteMapWebSafe_: null,\n\n /**\n * Our default alphabet, shared between\n * ENCODED_VALS and ENCODED_VALS_WEBSAFE\n */\n ENCODED_VALS_BASE:\n 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + 'abcdefghijklmnopqrstuvwxyz' + '0123456789',\n\n /**\n * Our default alphabet. Value 64 (=) is special; it means \"nothing.\"\n */\n get ENCODED_VALS() {\n return this.ENCODED_VALS_BASE + '+/=';\n },\n\n /**\n * Our websafe alphabet.\n */\n get ENCODED_VALS_WEBSAFE() {\n return this.ENCODED_VALS_BASE + '-_.';\n },\n\n /**\n * Whether this browser supports the atob and btoa functions. This extension\n * started at Mozilla but is now implemented by many browsers. We use the\n * ASSUME_* variables to avoid pulling in the full useragent detection library\n * but still allowing the standard per-browser compilations.\n *\n */\n HAS_NATIVE_SUPPORT: typeof atob === 'function',\n\n /**\n * Base64-encode an array of bytes.\n *\n * @param input An array of bytes (numbers with\n * value in [0, 255]) to encode.\n * @param webSafe Boolean indicating we should use the\n * alternative alphabet.\n * @return The base64 encoded string.\n */\n encodeByteArray(input: number[] | Uint8Array, webSafe?: boolean): string {\n if (!Array.isArray(input)) {\n throw Error('encodeByteArray takes an array as a parameter');\n }\n\n this.init_();\n\n const byteToCharMap = webSafe\n ? this.byteToCharMapWebSafe_!\n : this.byteToCharMap_!;\n\n const output = [];\n\n for (let i = 0; i < input.length; i += 3) {\n const byte1 = input[i];\n const haveByte2 = i + 1 < input.length;\n const byte2 = haveByte2 ? input[i + 1] : 0;\n const haveByte3 = i + 2 < input.length;\n const byte3 = haveByte3 ? input[i + 2] : 0;\n\n const outByte1 = byte1 >> 2;\n const outByte2 = ((byte1 & 0x03) << 4) | (byte2 >> 4);\n let outByte3 = ((byte2 & 0x0f) << 2) | (byte3 >> 6);\n let outByte4 = byte3 & 0x3f;\n\n if (!haveByte3) {\n outByte4 = 64;\n\n if (!haveByte2) {\n outByte3 = 64;\n }\n }\n\n output.push(\n byteToCharMap[outByte1],\n byteToCharMap[outByte2],\n byteToCharMap[outByte3],\n byteToCharMap[outByte4]\n );\n }\n\n return output.join('');\n },\n\n /**\n * Base64-encode a string.\n *\n * @param input A string to encode.\n * @param webSafe If true, we should use the\n * alternative alphabet.\n * @return The base64 encoded string.\n */\n encodeString(input: string, webSafe?: boolean): string {\n // Shortcut for Mozilla browsers that implement\n // a native base64 encoder in the form of \"btoa/atob\"\n if (this.HAS_NATIVE_SUPPORT && !webSafe) {\n return btoa(input);\n }\n return this.encodeByteArray(stringToByteArray(input), webSafe);\n },\n\n /**\n * Base64-decode a string.\n *\n * @param input to decode.\n * @param webSafe True if we should use the\n * alternative alphabet.\n * @return string representing the decoded value.\n */\n decodeString(input: string, webSafe: boolean): string {\n // Shortcut for Mozilla browsers that implement\n // a native base64 encoder in the form of \"btoa/atob\"\n if (this.HAS_NATIVE_SUPPORT && !webSafe) {\n return atob(input);\n }\n return byteArrayToString(this.decodeStringToByteArray(input, webSafe));\n },\n\n /**\n * Base64-decode a string.\n *\n * In base-64 decoding, groups of four characters are converted into three\n * bytes. If the encoder did not apply padding, the input length may not\n * be a multiple of 4.\n *\n * In this case, the last group will have fewer than 4 characters, and\n * padding will be inferred. If the group has one or two characters, it decodes\n * to one byte. If the group has three characters, it decodes to two bytes.\n *\n * @param input Input to decode.\n * @param webSafe True if we should use the web-safe alphabet.\n * @return bytes representing the decoded value.\n */\n decodeStringToByteArray(input: string, webSafe: boolean): number[] {\n this.init_();\n\n const charToByteMap = webSafe\n ? this.charToByteMapWebSafe_!\n : this.charToByteMap_!;\n\n const output: number[] = [];\n\n for (let i = 0; i < input.length; ) {\n const byte1 = charToByteMap[input.charAt(i++)];\n\n const haveByte2 = i < input.length;\n const byte2 = haveByte2 ? charToByteMap[input.charAt(i)] : 0;\n ++i;\n\n const haveByte3 = i < input.length;\n const byte3 = haveByte3 ? charToByteMap[input.charAt(i)] : 64;\n ++i;\n\n const haveByte4 = i < input.length;\n const byte4 = haveByte4 ? charToByteMap[input.charAt(i)] : 64;\n ++i;\n\n if (byte1 == null || byte2 == null || byte3 == null || byte4 == null) {\n throw Error();\n }\n\n const outByte1 = (byte1 << 2) | (byte2 >> 4);\n output.push(outByte1);\n\n if (byte3 !== 64) {\n const outByte2 = ((byte2 << 4) & 0xf0) | (byte3 >> 2);\n output.push(outByte2);\n\n if (byte4 !== 64) {\n const outByte3 = ((byte3 << 6) & 0xc0) | byte4;\n output.push(outByte3);\n }\n }\n }\n\n return output;\n },\n\n /**\n * Lazy static initialization function. Called before\n * accessing any of the static map variables.\n * @private\n */\n init_() {\n if (!this.byteToCharMap_) {\n this.byteToCharMap_ = {};\n this.charToByteMap_ = {};\n this.byteToCharMapWebSafe_ = {};\n this.charToByteMapWebSafe_ = {};\n\n // We want quick mappings back and forth, so we precompute two maps.\n for (let i = 0; i < this.ENCODED_VALS.length; i++) {\n this.byteToCharMap_[i] = this.ENCODED_VALS.charAt(i);\n this.charToByteMap_[this.byteToCharMap_[i]] = i;\n this.byteToCharMapWebSafe_[i] = this.ENCODED_VALS_WEBSAFE.charAt(i);\n this.charToByteMapWebSafe_[this.byteToCharMapWebSafe_[i]] = i;\n\n // Be forgiving when decoding and correctly decode both encodings.\n if (i >= this.ENCODED_VALS_BASE.length) {\n this.charToByteMap_[this.ENCODED_VALS_WEBSAFE.charAt(i)] = i;\n this.charToByteMapWebSafe_[this.ENCODED_VALS.charAt(i)] = i;\n }\n }\n }\n }\n};\n\n/**\n * URL-safe base64 encoding\n */\nexport const base64Encode = function (str: string): string {\n const utf8Bytes = stringToByteArray(str);\n return base64.encodeByteArray(utf8Bytes, true);\n};\n\n/**\n * URL-safe base64 encoding (without \".\" padding in the end).\n * e.g. Used in JSON Web Token (JWT) parts.\n */\nexport const base64urlEncodeWithoutPadding = function (str: string): string {\n // Use base64url encoding and remove padding in the end (dot characters).\n return base64Encode(str).replace(/\\./g, '');\n};\n\n/**\n * URL-safe base64 decoding\n *\n * NOTE: DO NOT use the global atob() function - it does NOT support the\n * base64Url variant encoding.\n *\n * @param str To be decoded\n * @return Decoded result, if possible\n */\nexport const base64Decode = function (str: string): string | null {\n try {\n return base64.decodeString(str, true);\n } catch (e) {\n console.error('base64Decode failed: ', e);\n }\n return null;\n};\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Do a deep-copy of basic JavaScript Objects or Arrays.\n */\nexport function deepCopy(value: T): T {\n return deepExtend(undefined, value) as T;\n}\n\n/**\n * Copy properties from source to target (recursively allows extension\n * of Objects and Arrays). Scalar values in the target are over-written.\n * If target is undefined, an object of the appropriate type will be created\n * (and returned).\n *\n * We recursively copy all child properties of plain Objects in the source- so\n * that namespace- like dictionaries are merged.\n *\n * Note that the target can be a function, in which case the properties in\n * the source Object are copied onto it as static properties of the Function.\n *\n * Note: we don't merge __proto__ to prevent prototype pollution\n */\nexport function deepExtend(target: unknown, source: unknown): unknown {\n if (!(source instanceof Object)) {\n return source;\n }\n\n switch (source.constructor) {\n case Date:\n // Treat Dates like scalars; if the target date object had any child\n // properties - they will be lost!\n const dateValue = source as Date;\n return new Date(dateValue.getTime());\n\n case Object:\n if (target === undefined) {\n target = {};\n }\n break;\n case Array:\n // Always copy the array source and overwrite the target.\n target = [];\n break;\n\n default:\n // Not a plain Object - treat it as a scalar.\n return source;\n }\n\n for (const prop in source) {\n // use isValidKey to guard against prototype pollution. See https://snyk.io/vuln/SNYK-JS-LODASH-450202\n if (!source.hasOwnProperty(prop) || !isValidKey(prop)) {\n continue;\n }\n (target as Record)[prop] = deepExtend(\n (target as Record)[prop],\n (source as Record)[prop]\n );\n }\n\n return target;\n}\n\nfunction isValidKey(key: string): boolean {\n return key !== '__proto__';\n}\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport class Deferred {\n promise: Promise;\n reject: (value?: unknown) => void = () => {};\n resolve: (value?: unknown) => void = () => {};\n constructor() {\n this.promise = new Promise((resolve, reject) => {\n this.resolve = resolve as (value?: unknown) => void;\n this.reject = reject as (value?: unknown) => void;\n });\n }\n\n /**\n * Our API internals are not promiseified and cannot because our callback APIs have subtle expectations around\n * invoking promises inline, which Promises are forbidden to do. This method accepts an optional node-style callback\n * and returns a node-style callback which will resolve or reject the Deferred's promise.\n */\n wrapCallback(\n callback?: (error?: unknown, value?: unknown) => void\n ): (error: unknown, value?: unknown) => void {\n return (error, value?) => {\n if (error) {\n this.reject(error);\n } else {\n this.resolve(value);\n }\n if (typeof callback === 'function') {\n // Attaching noop handler just in case developer wasn't expecting\n // promises\n this.promise.catch(() => {});\n\n // Some of our callbacks don't expect a value and our own tests\n // assert that the parameter length is 1\n if (callback.length === 1) {\n callback(error);\n } else {\n callback(error, value);\n }\n }\n };\n }\n}\n", "/**\n * @license\n * Copyright 2021 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { base64urlEncodeWithoutPadding } from './crypt';\n\n// Firebase Auth tokens contain snake_case claims following the JWT standard / convention.\n/* eslint-disable camelcase */\n\nexport type FirebaseSignInProvider =\n | 'custom'\n | 'email'\n | 'password'\n | 'phone'\n | 'anonymous'\n | 'google.com'\n | 'facebook.com'\n | 'github.com'\n | 'twitter.com'\n | 'microsoft.com'\n | 'apple.com';\n\ninterface FirebaseIdToken {\n // Always set to https://securetoken.google.com/PROJECT_ID\n iss: string;\n\n // Always set to PROJECT_ID\n aud: string;\n\n // The user's unique ID\n sub: string;\n\n // The token issue time, in seconds since epoch\n iat: number;\n\n // The token expiry time, normally 'iat' + 3600\n exp: number;\n\n // The user's unique ID. Must be equal to 'sub'\n user_id: string;\n\n // The time the user authenticated, normally 'iat'\n auth_time: number;\n\n // The sign in provider, only set when the provider is 'anonymous'\n provider_id?: 'anonymous';\n\n // The user's primary email\n email?: string;\n\n // The user's email verification status\n email_verified?: boolean;\n\n // The user's primary phone number\n phone_number?: string;\n\n // The user's display name\n name?: string;\n\n // The user's profile photo URL\n picture?: string;\n\n // Information on all identities linked to this user\n firebase: {\n // The primary sign-in provider\n sign_in_provider: FirebaseSignInProvider;\n\n // A map of providers to the user's list of unique identifiers from\n // each provider\n identities?: { [provider in FirebaseSignInProvider]?: string[] };\n };\n\n // Custom claims set by the developer\n [claim: string]: unknown;\n\n uid?: never; // Try to catch a common mistake of \"uid\" (should be \"sub\" instead).\n}\n\nexport type EmulatorMockTokenOptions = ({ user_id: string } | { sub: string }) &\n Partial;\n\nexport function createMockUserToken(\n token: EmulatorMockTokenOptions,\n projectId?: string\n): string {\n if (token.uid) {\n throw new Error(\n 'The \"uid\" field is no longer supported by mockUserToken. Please use \"sub\" instead for Firebase Auth User ID.'\n );\n }\n // Unsecured JWTs use \"none\" as the algorithm.\n const header = {\n alg: 'none',\n type: 'JWT'\n };\n\n const project = projectId || 'demo-project';\n const iat = token.iat || 0;\n const sub = token.sub || token.user_id;\n if (!sub) {\n throw new Error(\"mockUserToken must contain 'sub' or 'user_id' field!\");\n }\n\n const payload: FirebaseIdToken = {\n // Set all required fields to decent defaults\n iss: `https://securetoken.google.com/${project}`,\n aud: project,\n iat,\n exp: iat + 3600,\n auth_time: iat,\n sub,\n user_id: sub,\n firebase: {\n sign_in_provider: 'custom',\n identities: {}\n },\n\n // Override with user options\n ...token\n };\n\n // Unsecured JWTs use the empty string as a signature.\n const signature = '';\n return [\n base64urlEncodeWithoutPadding(JSON.stringify(header)),\n base64urlEncodeWithoutPadding(JSON.stringify(payload)),\n signature\n ].join('.');\n}\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { CONSTANTS } from './constants';\n\n/**\n * Returns navigator.userAgent string or '' if it's not defined.\n * @return user agent string\n */\nexport function getUA(): string {\n if (\n typeof navigator !== 'undefined' &&\n typeof navigator['userAgent'] === 'string'\n ) {\n return navigator['userAgent'];\n } else {\n return '';\n }\n}\n\n/**\n * Detect Cordova / PhoneGap / Ionic frameworks on a mobile device.\n *\n * Deliberately does not rely on checking `file://` URLs (as this fails PhoneGap\n * in the Ripple emulator) nor Cordova `onDeviceReady`, which would normally\n * wait for a callback.\n */\nexport function isMobileCordova(): boolean {\n return (\n typeof window !== 'undefined' &&\n // @ts-ignore Setting up an broadly applicable index signature for Window\n // just to deal with this case would probably be a bad idea.\n !!(window['cordova'] || window['phonegap'] || window['PhoneGap']) &&\n /ios|iphone|ipod|ipad|android|blackberry|iemobile/i.test(getUA())\n );\n}\n\n/**\n * Detect Node.js.\n *\n * @return true if Node.js environment is detected.\n */\n// Node detection logic from: https://github.com/iliakan/detect-node/\nexport function isNode(): boolean {\n try {\n return (\n Object.prototype.toString.call(global.process) === '[object process]'\n );\n } catch (e) {\n return false;\n }\n}\n\n/**\n * Detect Browser Environment\n */\nexport function isBrowser(): boolean {\n return typeof self === 'object' && self.self === self;\n}\n\n/**\n * Detect browser extensions (Chrome and Firefox at least).\n */\ninterface BrowserRuntime {\n id?: unknown;\n}\ndeclare const chrome: { runtime?: BrowserRuntime };\ndeclare const browser: { runtime?: BrowserRuntime };\nexport function isBrowserExtension(): boolean {\n const runtime =\n typeof chrome === 'object'\n ? chrome.runtime\n : typeof browser === 'object'\n ? browser.runtime\n : undefined;\n return typeof runtime === 'object' && runtime.id !== undefined;\n}\n\n/**\n * Detect React Native.\n *\n * @return true if ReactNative environment is detected.\n */\nexport function isReactNative(): boolean {\n return (\n typeof navigator === 'object' && navigator['product'] === 'ReactNative'\n );\n}\n\n/** Detects Electron apps. */\nexport function isElectron(): boolean {\n return getUA().indexOf('Electron/') >= 0;\n}\n\n/** Detects Internet Explorer. */\nexport function isIE(): boolean {\n const ua = getUA();\n return ua.indexOf('MSIE ') >= 0 || ua.indexOf('Trident/') >= 0;\n}\n\n/** Detects Universal Windows Platform apps. */\nexport function isUWP(): boolean {\n return getUA().indexOf('MSAppHost/') >= 0;\n}\n\n/**\n * Detect whether the current SDK build is the Node version.\n *\n * @return true if it's the Node SDK build.\n */\nexport function isNodeSdk(): boolean {\n return CONSTANTS.NODE_CLIENT === true || CONSTANTS.NODE_ADMIN === true;\n}\n\n/** Returns true if we are running in Safari. */\nexport function isSafari(): boolean {\n return (\n !isNode() &&\n navigator.userAgent.includes('Safari') &&\n !navigator.userAgent.includes('Chrome')\n );\n}\n\n/**\n * This method checks if indexedDB is supported by current browser/service worker context\n * @return true if indexedDB is supported by current browser/service worker context\n */\nexport function isIndexedDBAvailable(): boolean {\n return typeof indexedDB === 'object';\n}\n\n/**\n * This method validates browser/sw context for indexedDB by opening a dummy indexedDB database and reject\n * if errors occur during the database open operation.\n *\n * @throws exception if current browser/sw context can't run idb.open (ex: Safari iframe, Firefox\n * private browsing)\n */\nexport function validateIndexedDBOpenable(): Promise {\n return new Promise((resolve, reject) => {\n try {\n let preExist: boolean = true;\n const DB_CHECK_NAME =\n 'validate-browser-context-for-indexeddb-analytics-module';\n const request = self.indexedDB.open(DB_CHECK_NAME);\n request.onsuccess = () => {\n request.result.close();\n // delete database only when it doesn't pre-exist\n if (!preExist) {\n self.indexedDB.deleteDatabase(DB_CHECK_NAME);\n }\n resolve(true);\n };\n request.onupgradeneeded = () => {\n preExist = false;\n };\n\n request.onerror = () => {\n reject(request.error?.message || '');\n };\n } catch (error) {\n reject(error);\n }\n });\n}\n\n/**\n *\n * This method checks whether cookie is enabled within current browser\n * @return true if cookie is enabled within current browser\n */\nexport function areCookiesEnabled(): boolean {\n if (typeof navigator === 'undefined' || !navigator.cookieEnabled) {\n return false;\n }\n return true;\n}\n\n/**\n * Polyfill for `globalThis` object.\n * @returns the `globalThis` object for the given environment.\n */\nexport function getGlobal(): typeof globalThis {\n if (typeof self !== 'undefined') {\n return self;\n }\n if (typeof window !== 'undefined') {\n return window;\n }\n if (typeof global !== 'undefined') {\n return global;\n }\n throw new Error('Unable to locate global object.');\n}\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/**\n * @fileoverview Standardized Firebase Error.\n *\n * Usage:\n *\n * // Typescript string literals for type-safe codes\n * type Err =\n * 'unknown' |\n * 'object-not-found'\n * ;\n *\n * // Closure enum for type-safe error codes\n * // at-enum {string}\n * var Err = {\n * UNKNOWN: 'unknown',\n * OBJECT_NOT_FOUND: 'object-not-found',\n * }\n *\n * let errors: Map = {\n * 'generic-error': \"Unknown error\",\n * 'file-not-found': \"Could not find file: {$file}\",\n * };\n *\n * // Type-safe function - must pass a valid error code as param.\n * let error = new ErrorFactory('service', 'Service', errors);\n *\n * ...\n * throw error.create(Err.GENERIC);\n * ...\n * throw error.create(Err.FILE_NOT_FOUND, {'file': fileName});\n * ...\n * // Service: Could not file file: foo.txt (service/file-not-found).\n *\n * catch (e) {\n * assert(e.message === \"Could not find file: foo.txt.\");\n * if ((e as FirebaseError)?.code === 'service/file-not-found') {\n * console.log(\"Could not read file: \" + e['file']);\n * }\n * }\n */\n\nexport type ErrorMap = {\n readonly [K in ErrorCode]: string;\n};\n\nconst ERROR_NAME = 'FirebaseError';\n\nexport interface StringLike {\n toString(): string;\n}\n\nexport interface ErrorData {\n [key: string]: unknown;\n}\n\n// Based on code from:\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error#Custom_Error_Types\nexport class FirebaseError extends Error {\n /** The custom name for all FirebaseErrors. */\n readonly name: string = ERROR_NAME;\n\n constructor(\n /** The error code for this error. */\n readonly code: string,\n message: string,\n /** Custom data for this error. */\n public customData?: Record\n ) {\n super(message);\n\n // Fix For ES5\n // https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work\n Object.setPrototypeOf(this, FirebaseError.prototype);\n\n // Maintains proper stack trace for where our error was thrown.\n // Only available on V8.\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, ErrorFactory.prototype.create);\n }\n }\n}\n\nexport class ErrorFactory<\n ErrorCode extends string,\n ErrorParams extends { readonly [K in ErrorCode]?: ErrorData } = {}\n> {\n constructor(\n private readonly service: string,\n private readonly serviceName: string,\n private readonly errors: ErrorMap\n ) {}\n\n create(\n code: K,\n ...data: K extends keyof ErrorParams ? [ErrorParams[K]] : []\n ): FirebaseError {\n const customData = (data[0] as ErrorData) || {};\n const fullCode = `${this.service}/${code}`;\n const template = this.errors[code];\n\n const message = template ? replaceTemplate(template, customData) : 'Error';\n // Service Name: Error message (service/code).\n const fullMessage = `${this.serviceName}: ${message} (${fullCode}).`;\n\n const error = new FirebaseError(fullCode, fullMessage, customData);\n\n return error;\n }\n}\n\nfunction replaceTemplate(template: string, data: ErrorData): string {\n return template.replace(PATTERN, (_, key) => {\n const value = data[key];\n return value != null ? String(value) : `<${key}?>`;\n });\n}\n\nconst PATTERN = /\\{\\$([^}]+)}/g;\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Evaluates a JSON string into a javascript object.\n *\n * @param {string} str A string containing JSON.\n * @return {*} The javascript object representing the specified JSON.\n */\nexport function jsonEval(str: string): unknown {\n return JSON.parse(str);\n}\n\n/**\n * Returns JSON representing a javascript object.\n * @param {*} data Javascript object to be stringified.\n * @return {string} The JSON contents of the object.\n */\nexport function stringify(data: unknown): string {\n return JSON.stringify(data);\n}\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { base64Decode } from './crypt';\nimport { jsonEval } from './json';\n\ninterface Claims {\n [key: string]: {};\n}\n\ninterface DecodedToken {\n header: object;\n claims: Claims;\n data: object;\n signature: string;\n}\n\n/**\n * Decodes a Firebase auth. token into constituent parts.\n *\n * Notes:\n * - May return with invalid / incomplete claims if there's no native base64 decoding support.\n * - Doesn't check if the token is actually valid.\n */\nexport const decode = function (token: string): DecodedToken {\n let header = {},\n claims: Claims = {},\n data = {},\n signature = '';\n\n try {\n const parts = token.split('.');\n header = jsonEval(base64Decode(parts[0]) || '') as object;\n claims = jsonEval(base64Decode(parts[1]) || '') as Claims;\n signature = parts[2];\n data = claims['d'] || {};\n delete claims['d'];\n } catch (e) {}\n\n return {\n header,\n claims,\n data,\n signature\n };\n};\n\ninterface DecodedToken {\n header: object;\n claims: Claims;\n data: object;\n signature: string;\n}\n\n/**\n * Decodes a Firebase auth. token and checks the validity of its time-based claims. Will return true if the\n * token is within the time window authorized by the 'nbf' (not-before) and 'iat' (issued-at) claims.\n *\n * Notes:\n * - May return a false negative if there's no native base64 decoding support.\n * - Doesn't check if the token is actually valid.\n */\nexport const isValidTimestamp = function (token: string): boolean {\n const claims: Claims = decode(token).claims;\n const now: number = Math.floor(new Date().getTime() / 1000);\n let validSince: number = 0,\n validUntil: number = 0;\n\n if (typeof claims === 'object') {\n if (claims.hasOwnProperty('nbf')) {\n validSince = claims['nbf'] as number;\n } else if (claims.hasOwnProperty('iat')) {\n validSince = claims['iat'] as number;\n }\n\n if (claims.hasOwnProperty('exp')) {\n validUntil = claims['exp'] as number;\n } else {\n // token will expire after 24h by default\n validUntil = validSince + 86400;\n }\n }\n\n return (\n !!now &&\n !!validSince &&\n !!validUntil &&\n now >= validSince &&\n now <= validUntil\n );\n};\n\n/**\n * Decodes a Firebase auth. token and returns its issued at time if valid, null otherwise.\n *\n * Notes:\n * - May return null if there's no native base64 decoding support.\n * - Doesn't check if the token is actually valid.\n */\nexport const issuedAtTime = function (token: string): number | null {\n const claims: Claims = decode(token).claims;\n if (typeof claims === 'object' && claims.hasOwnProperty('iat')) {\n return claims['iat'] as number;\n }\n return null;\n};\n\n/**\n * Decodes a Firebase auth. token and checks the validity of its format. Expects a valid issued-at time.\n *\n * Notes:\n * - May return a false negative if there's no native base64 decoding support.\n * - Doesn't check if the token is actually valid.\n */\nexport const isValidFormat = function (token: string): boolean {\n const decoded = decode(token),\n claims = decoded.claims;\n\n return !!claims && typeof claims === 'object' && claims.hasOwnProperty('iat');\n};\n\n/**\n * Attempts to peer into an auth token and determine if it's an admin auth token by looking at the claims portion.\n *\n * Notes:\n * - May return a false negative if there's no native base64 decoding support.\n * - Doesn't check if the token is actually valid.\n */\nexport const isAdmin = function (token: string): boolean {\n const claims: Claims = decode(token).claims;\n return typeof claims === 'object' && claims['admin'] === true;\n};\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport function contains(obj: T, key: string): boolean {\n return Object.prototype.hasOwnProperty.call(obj, key);\n}\n\nexport function safeGet(\n obj: T,\n key: K\n): T[K] | undefined {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n return obj[key];\n } else {\n return undefined;\n }\n}\n\nexport function isEmpty(obj: object): obj is {} {\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n return false;\n }\n }\n return true;\n}\n\nexport function map(\n obj: { [key in K]: V },\n fn: (value: V, key: K, obj: { [key in K]: V }) => U,\n contextObj?: unknown\n): { [key in K]: U } {\n const res: Partial<{ [key in K]: U }> = {};\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n res[key] = fn.call(contextObj, obj[key], key, obj);\n }\n }\n return res as { [key in K]: U };\n}\n\n/**\n * Deep equal two objects. Support Arrays and Objects.\n */\nexport function deepEqual(a: object, b: object): boolean {\n if (a === b) {\n return true;\n }\n\n const aKeys = Object.keys(a);\n const bKeys = Object.keys(b);\n for (const k of aKeys) {\n if (!bKeys.includes(k)) {\n return false;\n }\n\n const aProp = (a as Record)[k];\n const bProp = (b as Record)[k];\n if (isObject(aProp) && isObject(bProp)) {\n if (!deepEqual(aProp, bProp)) {\n return false;\n }\n } else if (aProp !== bProp) {\n return false;\n }\n }\n\n for (const k of bKeys) {\n if (!aKeys.includes(k)) {\n return false;\n }\n }\n return true;\n}\n\nfunction isObject(thing: unknown): thing is object {\n return thing !== null && typeof thing === 'object';\n}\n", "/**\n * @license\n * Copyright 2022 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Deferred } from './deferred';\n\n/**\n * Rejects if the given promise doesn't resolve in timeInMS milliseconds.\n * @internal\n */\nexport function promiseWithTimeout(\n promise: Promise,\n timeInMS = 2000\n): Promise {\n const deferredPromise = new Deferred();\n setTimeout(() => deferredPromise.reject('timeout!'), timeInMS);\n promise.then(deferredPromise.resolve, deferredPromise.reject);\n return deferredPromise.promise;\n}\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Returns a querystring-formatted string (e.g. &arg=val&arg2=val2) from a\n * params object (e.g. {arg: 'val', arg2: 'val2'})\n * Note: You must prepend it with ? when adding it to a URL.\n */\nexport function querystring(querystringParams: {\n [key: string]: string | number;\n}): string {\n const params = [];\n for (const [key, value] of Object.entries(querystringParams)) {\n if (Array.isArray(value)) {\n value.forEach(arrayVal => {\n params.push(\n encodeURIComponent(key) + '=' + encodeURIComponent(arrayVal)\n );\n });\n } else {\n params.push(encodeURIComponent(key) + '=' + encodeURIComponent(value));\n }\n }\n return params.length ? '&' + params.join('&') : '';\n}\n\n/**\n * Decodes a querystring (e.g. ?arg=val&arg2=val2) into a params object\n * (e.g. {arg: 'val', arg2: 'val2'})\n */\nexport function querystringDecode(querystring: string): Record {\n const obj: Record = {};\n const tokens = querystring.replace(/^\\?/, '').split('&');\n\n tokens.forEach(token => {\n if (token) {\n const [key, value] = token.split('=');\n obj[decodeURIComponent(key)] = decodeURIComponent(value);\n }\n });\n return obj;\n}\n\n/**\n * Extract the query string part of a URL, including the leading question mark (if present).\n */\nexport function extractQuerystring(url: string): string {\n const queryStart = url.indexOf('?');\n if (!queryStart) {\n return '';\n }\n const fragmentStart = url.indexOf('#', queryStart);\n return url.substring(\n queryStart,\n fragmentStart > 0 ? fragmentStart : undefined\n );\n}\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * @fileoverview SHA-1 cryptographic hash.\n * Variable names follow the notation in FIPS PUB 180-3:\n * http://csrc.nist.gov/publications/fips/fips180-3/fips180-3_final.pdf.\n *\n * Usage:\n * var sha1 = new sha1();\n * sha1.update(bytes);\n * var hash = sha1.digest();\n *\n * Performance:\n * Chrome 23: ~400 Mbit/s\n * Firefox 16: ~250 Mbit/s\n *\n */\n\n/**\n * SHA-1 cryptographic hash constructor.\n *\n * The properties declared here are discussed in the above algorithm document.\n * @constructor\n * @final\n * @struct\n */\nexport class Sha1 {\n /**\n * Holds the previous values of accumulated variables a-e in the compress_\n * function.\n * @private\n */\n private chain_: number[] = [];\n\n /**\n * A buffer holding the partially computed hash result.\n * @private\n */\n private buf_: number[] = [];\n\n /**\n * An array of 80 bytes, each a part of the message to be hashed. Referred to\n * as the message schedule in the docs.\n * @private\n */\n private W_: number[] = [];\n\n /**\n * Contains data needed to pad messages less than 64 bytes.\n * @private\n */\n private pad_: number[] = [];\n\n /**\n * @private {number}\n */\n private inbuf_: number = 0;\n\n /**\n * @private {number}\n */\n private total_: number = 0;\n\n blockSize: number;\n\n constructor() {\n this.blockSize = 512 / 8;\n\n this.pad_[0] = 128;\n for (let i = 1; i < this.blockSize; ++i) {\n this.pad_[i] = 0;\n }\n\n this.reset();\n }\n\n reset(): void {\n this.chain_[0] = 0x67452301;\n this.chain_[1] = 0xefcdab89;\n this.chain_[2] = 0x98badcfe;\n this.chain_[3] = 0x10325476;\n this.chain_[4] = 0xc3d2e1f0;\n\n this.inbuf_ = 0;\n this.total_ = 0;\n }\n\n /**\n * Internal compress helper function.\n * @param buf Block to compress.\n * @param offset Offset of the block in the buffer.\n * @private\n */\n compress_(buf: number[] | Uint8Array | string, offset?: number): void {\n if (!offset) {\n offset = 0;\n }\n\n const W = this.W_;\n\n // get 16 big endian words\n if (typeof buf === 'string') {\n for (let i = 0; i < 16; i++) {\n // TODO(user): [bug 8140122] Recent versions of Safari for Mac OS and iOS\n // have a bug that turns the post-increment ++ operator into pre-increment\n // during JIT compilation. We have code that depends heavily on SHA-1 for\n // correctness and which is affected by this bug, so I've removed all uses\n // of post-increment ++ in which the result value is used. We can revert\n // this change once the Safari bug\n // (https://bugs.webkit.org/show_bug.cgi?id=109036) has been fixed and\n // most clients have been updated.\n W[i] =\n (buf.charCodeAt(offset) << 24) |\n (buf.charCodeAt(offset + 1) << 16) |\n (buf.charCodeAt(offset + 2) << 8) |\n buf.charCodeAt(offset + 3);\n offset += 4;\n }\n } else {\n for (let i = 0; i < 16; i++) {\n W[i] =\n (buf[offset] << 24) |\n (buf[offset + 1] << 16) |\n (buf[offset + 2] << 8) |\n buf[offset + 3];\n offset += 4;\n }\n }\n\n // expand to 80 words\n for (let i = 16; i < 80; i++) {\n const t = W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16];\n W[i] = ((t << 1) | (t >>> 31)) & 0xffffffff;\n }\n\n let a = this.chain_[0];\n let b = this.chain_[1];\n let c = this.chain_[2];\n let d = this.chain_[3];\n let e = this.chain_[4];\n let f, k;\n\n // TODO(user): Try to unroll this loop to speed up the computation.\n for (let i = 0; i < 80; i++) {\n if (i < 40) {\n if (i < 20) {\n f = d ^ (b & (c ^ d));\n k = 0x5a827999;\n } else {\n f = b ^ c ^ d;\n k = 0x6ed9eba1;\n }\n } else {\n if (i < 60) {\n f = (b & c) | (d & (b | c));\n k = 0x8f1bbcdc;\n } else {\n f = b ^ c ^ d;\n k = 0xca62c1d6;\n }\n }\n\n const t = (((a << 5) | (a >>> 27)) + f + e + k + W[i]) & 0xffffffff;\n e = d;\n d = c;\n c = ((b << 30) | (b >>> 2)) & 0xffffffff;\n b = a;\n a = t;\n }\n\n this.chain_[0] = (this.chain_[0] + a) & 0xffffffff;\n this.chain_[1] = (this.chain_[1] + b) & 0xffffffff;\n this.chain_[2] = (this.chain_[2] + c) & 0xffffffff;\n this.chain_[3] = (this.chain_[3] + d) & 0xffffffff;\n this.chain_[4] = (this.chain_[4] + e) & 0xffffffff;\n }\n\n update(bytes?: number[] | Uint8Array | string, length?: number): void {\n // TODO(johnlenz): tighten the function signature and remove this check\n if (bytes == null) {\n return;\n }\n\n if (length === undefined) {\n length = bytes.length;\n }\n\n const lengthMinusBlock = length - this.blockSize;\n let n = 0;\n // Using local instead of member variables gives ~5% speedup on Firefox 16.\n const buf = this.buf_;\n let inbuf = this.inbuf_;\n\n // The outer while loop should execute at most twice.\n while (n < length) {\n // When we have no data in the block to top up, we can directly process the\n // input buffer (assuming it contains sufficient data). This gives ~25%\n // speedup on Chrome 23 and ~15% speedup on Firefox 16, but requires that\n // the data is provided in large chunks (or in multiples of 64 bytes).\n if (inbuf === 0) {\n while (n <= lengthMinusBlock) {\n this.compress_(bytes, n);\n n += this.blockSize;\n }\n }\n\n if (typeof bytes === 'string') {\n while (n < length) {\n buf[inbuf] = bytes.charCodeAt(n);\n ++inbuf;\n ++n;\n if (inbuf === this.blockSize) {\n this.compress_(buf);\n inbuf = 0;\n // Jump to the outer loop so we use the full-block optimization.\n break;\n }\n }\n } else {\n while (n < length) {\n buf[inbuf] = bytes[n];\n ++inbuf;\n ++n;\n if (inbuf === this.blockSize) {\n this.compress_(buf);\n inbuf = 0;\n // Jump to the outer loop so we use the full-block optimization.\n break;\n }\n }\n }\n }\n\n this.inbuf_ = inbuf;\n this.total_ += length;\n }\n\n /** @override */\n digest(): number[] {\n const digest: number[] = [];\n let totalBits = this.total_ * 8;\n\n // Add pad 0x80 0x00*.\n if (this.inbuf_ < 56) {\n this.update(this.pad_, 56 - this.inbuf_);\n } else {\n this.update(this.pad_, this.blockSize - (this.inbuf_ - 56));\n }\n\n // Add # bits.\n for (let i = this.blockSize - 1; i >= 56; i--) {\n this.buf_[i] = totalBits & 255;\n totalBits /= 256; // Don't use bit-shifting here!\n }\n\n this.compress_(this.buf_);\n\n let n = 0;\n for (let i = 0; i < 5; i++) {\n for (let j = 24; j >= 0; j -= 8) {\n digest[n] = (this.chain_[i] >> j) & 255;\n ++n;\n }\n }\n return digest;\n }\n}\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nexport type NextFn = (value: T) => void;\nexport type ErrorFn = (error: Error) => void;\nexport type CompleteFn = () => void;\n\nexport interface Observer {\n // Called once for each value in a stream of values.\n next: NextFn;\n\n // A stream terminates by a single call to EITHER error() or complete().\n error: ErrorFn;\n\n // No events will be sent to next() once complete() is called.\n complete: CompleteFn;\n}\n\nexport type PartialObserver = Partial>;\n\n// TODO: Support also Unsubscribe.unsubscribe?\nexport type Unsubscribe = () => void;\n\n/**\n * The Subscribe interface has two forms - passing the inline function\n * callbacks, or a object interface with callback properties.\n */\nexport interface Subscribe {\n (next?: NextFn, error?: ErrorFn, complete?: CompleteFn): Unsubscribe;\n (observer: PartialObserver): Unsubscribe;\n}\n\nexport interface Observable {\n // Subscribe method\n subscribe: Subscribe;\n}\n\nexport type Executor = (observer: Observer) => void;\n\n/**\n * Helper to make a Subscribe function (just like Promise helps make a\n * Thenable).\n *\n * @param executor Function which can make calls to a single Observer\n * as a proxy.\n * @param onNoObservers Callback when count of Observers goes to zero.\n */\nexport function createSubscribe(\n executor: Executor,\n onNoObservers?: Executor\n): Subscribe {\n const proxy = new ObserverProxy(executor, onNoObservers);\n return proxy.subscribe.bind(proxy);\n}\n\n/**\n * Implement fan-out for any number of Observers attached via a subscribe\n * function.\n */\nclass ObserverProxy implements Observer {\n private observers: Array> | undefined = [];\n private unsubscribes: Unsubscribe[] = [];\n private onNoObservers: Executor | undefined;\n private observerCount = 0;\n // Micro-task scheduling by calling task.then().\n private task = Promise.resolve();\n private finalized = false;\n private finalError?: Error;\n\n /**\n * @param executor Function which can make calls to a single Observer\n * as a proxy.\n * @param onNoObservers Callback when count of Observers goes to zero.\n */\n constructor(executor: Executor, onNoObservers?: Executor) {\n this.onNoObservers = onNoObservers;\n // Call the executor asynchronously so subscribers that are called\n // synchronously after the creation of the subscribe function\n // can still receive the very first value generated in the executor.\n this.task\n .then(() => {\n executor(this);\n })\n .catch(e => {\n this.error(e);\n });\n }\n\n next(value: T): void {\n this.forEachObserver((observer: Observer) => {\n observer.next(value);\n });\n }\n\n error(error: Error): void {\n this.forEachObserver((observer: Observer) => {\n observer.error(error);\n });\n this.close(error);\n }\n\n complete(): void {\n this.forEachObserver((observer: Observer) => {\n observer.complete();\n });\n this.close();\n }\n\n /**\n * Subscribe function that can be used to add an Observer to the fan-out list.\n *\n * - We require that no event is sent to a subscriber sychronously to their\n * call to subscribe().\n */\n subscribe(\n nextOrObserver?: NextFn | PartialObserver,\n error?: ErrorFn,\n complete?: CompleteFn\n ): Unsubscribe {\n let observer: Observer;\n\n if (\n nextOrObserver === undefined &&\n error === undefined &&\n complete === undefined\n ) {\n throw new Error('Missing Observer.');\n }\n\n // Assemble an Observer object when passed as callback functions.\n if (\n implementsAnyMethods(nextOrObserver as { [key: string]: unknown }, [\n 'next',\n 'error',\n 'complete'\n ])\n ) {\n observer = nextOrObserver as Observer;\n } else {\n observer = {\n next: nextOrObserver as NextFn,\n error,\n complete\n } as Observer;\n }\n\n if (observer.next === undefined) {\n observer.next = noop as NextFn;\n }\n if (observer.error === undefined) {\n observer.error = noop as ErrorFn;\n }\n if (observer.complete === undefined) {\n observer.complete = noop as CompleteFn;\n }\n\n const unsub = this.unsubscribeOne.bind(this, this.observers!.length);\n\n // Attempt to subscribe to a terminated Observable - we\n // just respond to the Observer with the final error or complete\n // event.\n if (this.finalized) {\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.task.then(() => {\n try {\n if (this.finalError) {\n observer.error(this.finalError);\n } else {\n observer.complete();\n }\n } catch (e) {\n // nothing\n }\n return;\n });\n }\n\n this.observers!.push(observer as Observer);\n\n return unsub;\n }\n\n // Unsubscribe is synchronous - we guarantee that no events are sent to\n // any unsubscribed Observer.\n private unsubscribeOne(i: number): void {\n if (this.observers === undefined || this.observers[i] === undefined) {\n return;\n }\n\n delete this.observers[i];\n\n this.observerCount -= 1;\n if (this.observerCount === 0 && this.onNoObservers !== undefined) {\n this.onNoObservers(this);\n }\n }\n\n private forEachObserver(fn: (observer: Observer) => void): void {\n if (this.finalized) {\n // Already closed by previous event....just eat the additional values.\n return;\n }\n\n // Since sendOne calls asynchronously - there is no chance that\n // this.observers will become undefined.\n for (let i = 0; i < this.observers!.length; i++) {\n this.sendOne(i, fn);\n }\n }\n\n // Call the Observer via one of it's callback function. We are careful to\n // confirm that the observe has not been unsubscribed since this asynchronous\n // function had been queued.\n private sendOne(i: number, fn: (observer: Observer) => void): void {\n // Execute the callback asynchronously\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.task.then(() => {\n if (this.observers !== undefined && this.observers[i] !== undefined) {\n try {\n fn(this.observers[i]);\n } catch (e) {\n // Ignore exceptions raised in Observers or missing methods of an\n // Observer.\n // Log error to console. b/31404806\n if (typeof console !== 'undefined' && console.error) {\n console.error(e);\n }\n }\n }\n });\n }\n\n private close(err?: Error): void {\n if (this.finalized) {\n return;\n }\n this.finalized = true;\n if (err !== undefined) {\n this.finalError = err;\n }\n // Proxy is no longer needed - garbage collect references\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.task.then(() => {\n this.observers = undefined;\n this.onNoObservers = undefined;\n });\n }\n}\n\n/** Turn synchronous function into one called asynchronously. */\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport function async(fn: Function, onError?: ErrorFn): Function {\n return (...args: unknown[]) => {\n Promise.resolve(true)\n .then(() => {\n fn(...args);\n })\n .catch((error: Error) => {\n if (onError) {\n onError(error);\n }\n });\n };\n}\n\n/**\n * Return true if the object passed in implements any of the named methods.\n */\nfunction implementsAnyMethods(\n obj: { [key: string]: unknown },\n methods: string[]\n): boolean {\n if (typeof obj !== 'object' || obj === null) {\n return false;\n }\n\n for (const method of methods) {\n if (method in obj && typeof obj[method] === 'function') {\n return true;\n }\n }\n\n return false;\n}\n\nfunction noop(): void {\n // do nothing\n}\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Check to make sure the appropriate number of arguments are provided for a public function.\n * Throws an error if it fails.\n *\n * @param fnName The function name\n * @param minCount The minimum number of arguments to allow for the function call\n * @param maxCount The maximum number of argument to allow for the function call\n * @param argCount The actual number of arguments provided.\n */\nexport const validateArgCount = function (\n fnName: string,\n minCount: number,\n maxCount: number,\n argCount: number\n): void {\n let argError;\n if (argCount < minCount) {\n argError = 'at least ' + minCount;\n } else if (argCount > maxCount) {\n argError = maxCount === 0 ? 'none' : 'no more than ' + maxCount;\n }\n if (argError) {\n const error =\n fnName +\n ' failed: Was called with ' +\n argCount +\n (argCount === 1 ? ' argument.' : ' arguments.') +\n ' Expects ' +\n argError +\n '.';\n throw new Error(error);\n }\n};\n\n/**\n * Generates a string to prefix an error message about failed argument validation\n *\n * @param fnName The function name\n * @param argName The name of the argument\n * @return The prefix to add to the error thrown for validation.\n */\nexport function errorPrefix(fnName: string, argName: string): string {\n return `${fnName} failed: ${argName} argument `;\n}\n\n/**\n * @param fnName\n * @param argumentNumber\n * @param namespace\n * @param optional\n */\nexport function validateNamespace(\n fnName: string,\n namespace: string,\n optional: boolean\n): void {\n if (optional && !namespace) {\n return;\n }\n if (typeof namespace !== 'string') {\n //TODO: I should do more validation here. We only allow certain chars in namespaces.\n throw new Error(\n errorPrefix(fnName, 'namespace') + 'must be a valid firebase namespace.'\n );\n }\n}\n\nexport function validateCallback(\n fnName: string,\n argumentName: string,\n // eslint-disable-next-line @typescript-eslint/ban-types\n callback: Function,\n optional: boolean\n): void {\n if (optional && !callback) {\n return;\n }\n if (typeof callback !== 'function') {\n throw new Error(\n errorPrefix(fnName, argumentName) + 'must be a valid function.'\n );\n }\n}\n\nexport function validateContextObject(\n fnName: string,\n argumentName: string,\n context: unknown,\n optional: boolean\n): void {\n if (optional && !context) {\n return;\n }\n if (typeof context !== 'object' || context === null) {\n throw new Error(\n errorPrefix(fnName, argumentName) + 'must be a valid context object.'\n );\n }\n}\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { assert } from './assert';\n\n// Code originally came from goog.crypt.stringToUtf8ByteArray, but for some reason they\n// automatically replaced '\\r\\n' with '\\n', and they didn't handle surrogate pairs,\n// so it's been modified.\n\n// Note that not all Unicode characters appear as single characters in JavaScript strings.\n// fromCharCode returns the UTF-16 encoding of a character - so some Unicode characters\n// use 2 characters in Javascript. All 4-byte UTF-8 characters begin with a first\n// character in the range 0xD800 - 0xDBFF (the first character of a so-called surrogate\n// pair).\n// See http://www.ecma-international.org/ecma-262/5.1/#sec-15.1.3\n\n/**\n * @param {string} str\n * @return {Array}\n */\nexport const stringToByteArray = function (str: string): number[] {\n const out: number[] = [];\n let p = 0;\n for (let i = 0; i < str.length; i++) {\n let c = str.charCodeAt(i);\n\n // Is this the lead surrogate in a surrogate pair?\n if (c >= 0xd800 && c <= 0xdbff) {\n const high = c - 0xd800; // the high 10 bits.\n i++;\n assert(i < str.length, 'Surrogate pair missing trail surrogate.');\n const low = str.charCodeAt(i) - 0xdc00; // the low 10 bits.\n c = 0x10000 + (high << 10) + low;\n }\n\n if (c < 128) {\n out[p++] = c;\n } else if (c < 2048) {\n out[p++] = (c >> 6) | 192;\n out[p++] = (c & 63) | 128;\n } else if (c < 65536) {\n out[p++] = (c >> 12) | 224;\n out[p++] = ((c >> 6) & 63) | 128;\n out[p++] = (c & 63) | 128;\n } else {\n out[p++] = (c >> 18) | 240;\n out[p++] = ((c >> 12) & 63) | 128;\n out[p++] = ((c >> 6) & 63) | 128;\n out[p++] = (c & 63) | 128;\n }\n }\n return out;\n};\n\n/**\n * Calculate length without actually converting; useful for doing cheaper validation.\n * @param {string} str\n * @return {number}\n */\nexport const stringLength = function (str: string): number {\n let p = 0;\n for (let i = 0; i < str.length; i++) {\n const c = str.charCodeAt(i);\n if (c < 128) {\n p++;\n } else if (c < 2048) {\n p += 2;\n } else if (c >= 0xd800 && c <= 0xdbff) {\n // Lead surrogate of a surrogate pair. The pair together will take 4 bytes to represent.\n p += 4;\n i++; // skip trail surrogate.\n } else {\n p += 3;\n }\n }\n return p;\n};\n", "/**\n * @license\n * Copyright 2022 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Copied from https://stackoverflow.com/a/2117523\n * Generates a new uuid.\n * @public\n */\nexport const uuidv4 = function (): string {\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {\n const r = (Math.random() * 16) | 0,\n v = c === 'x' ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n};\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * The amount of milliseconds to exponentially increase.\n */\nconst DEFAULT_INTERVAL_MILLIS = 1000;\n\n/**\n * The factor to backoff by.\n * Should be a number greater than 1.\n */\nconst DEFAULT_BACKOFF_FACTOR = 2;\n\n/**\n * The maximum milliseconds to increase to.\n *\n *

Visible for testing\n */\nexport const MAX_VALUE_MILLIS = 4 * 60 * 60 * 1000; // Four hours, like iOS and Android.\n\n/**\n * The percentage of backoff time to randomize by.\n * See\n * http://go/safe-client-behavior#step-1-determine-the-appropriate-retry-interval-to-handle-spike-traffic\n * for context.\n *\n *

Visible for testing\n */\nexport const RANDOM_FACTOR = 0.5;\n\n/**\n * Based on the backoff method from\n * https://github.com/google/closure-library/blob/master/closure/goog/math/exponentialbackoff.js.\n * Extracted here so we don't need to pass metadata and a stateful ExponentialBackoff object around.\n */\nexport function calculateBackoffMillis(\n backoffCount: number,\n intervalMillis: number = DEFAULT_INTERVAL_MILLIS,\n backoffFactor: number = DEFAULT_BACKOFF_FACTOR\n): number {\n // Calculates an exponentially increasing value.\n // Deviation: calculates value from count and a constant interval, so we only need to save value\n // and count to restore state.\n const currBaseValue = intervalMillis * Math.pow(backoffFactor, backoffCount);\n\n // A random \"fuzz\" to avoid waves of retries.\n // Deviation: randomFactor is required.\n const randomWait = Math.round(\n // A fraction of the backoff value to add/subtract.\n // Deviation: changes multiplication order to improve readability.\n RANDOM_FACTOR *\n currBaseValue *\n // A random float (rounded to int by Math.round above) in the range [-1, 1]. Determines\n // if we add or subtract.\n (Math.random() - 0.5) *\n 2\n );\n\n // Limits backoff to max to avoid effectively permanent backoff.\n return Math.min(MAX_VALUE_MILLIS, currBaseValue + randomWait);\n}\n", "/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Provide English ordinal letters after a number\n */\nexport function ordinal(i: number): string {\n if (!Number.isFinite(i)) {\n return `${i}`;\n }\n return i + indicator(i);\n}\n\nfunction indicator(i: number): string {\n i = Math.abs(i);\n const cent = i % 100;\n if (cent >= 10 && cent <= 20) {\n return 'th';\n }\n const dec = i % 10;\n if (dec === 1) {\n return 'st';\n }\n if (dec === 2) {\n return 'nd';\n }\n if (dec === 3) {\n return 'rd';\n }\n return 'th';\n}\n", "/**\n * @license\n * Copyright 2021 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport interface Compat {\n _delegate: T;\n}\n\nexport function getModularInstance(\n service: Compat | ExpService\n): ExpService {\n if (service && (service as Compat)._delegate) {\n return (service as Compat)._delegate;\n } else {\n return service as ExpService;\n }\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n InstantiationMode,\n InstanceFactory,\n ComponentType,\n Dictionary,\n Name,\n onInstanceCreatedCallback\n} from './types';\n\n/**\n * Component for service name T, e.g. `auth`, `auth-internal`\n */\nexport class Component {\n multipleInstances = false;\n /**\n * Properties to be added to the service namespace\n */\n serviceProps: Dictionary = {};\n\n instantiationMode = InstantiationMode.LAZY;\n\n onInstanceCreated: onInstanceCreatedCallback | null = null;\n\n /**\n *\n * @param name The public service name, e.g. app, auth, firestore, database\n * @param instanceFactory Service factory responsible for creating the public interface\n * @param type whether the service provided by the component is public or private\n */\n constructor(\n readonly name: T,\n readonly instanceFactory: InstanceFactory,\n readonly type: ComponentType\n ) {}\n\n setInstantiationMode(mode: InstantiationMode): this {\n this.instantiationMode = mode;\n return this;\n }\n\n setMultipleInstances(multipleInstances: boolean): this {\n this.multipleInstances = multipleInstances;\n return this;\n }\n\n setServiceProps(props: Dictionary): this {\n this.serviceProps = props;\n return this;\n }\n\n setInstanceCreatedCallback(callback: onInstanceCreatedCallback): this {\n this.onInstanceCreated = callback;\n return this;\n }\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport const DEFAULT_ENTRY_NAME = '[DEFAULT]';\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Deferred } from '@firebase/util';\nimport { ComponentContainer } from './component_container';\nimport { DEFAULT_ENTRY_NAME } from './constants';\nimport {\n InitializeOptions,\n InstantiationMode,\n Name,\n NameServiceMapping,\n OnInitCallBack\n} from './types';\nimport { Component } from './component';\n\n/**\n * Provider for instance for service name T, e.g. 'auth', 'auth-internal'\n * NameServiceMapping[T] is an alias for the type of the instance\n */\nexport class Provider {\n private component: Component | null = null;\n private readonly instances: Map = new Map();\n private readonly instancesDeferred: Map<\n string,\n Deferred\n > = new Map();\n private readonly instancesOptions: Map> =\n new Map();\n private onInitCallbacks: Map>> = new Map();\n\n constructor(\n private readonly name: T,\n private readonly container: ComponentContainer\n ) {}\n\n /**\n * @param identifier A provider can provide mulitple instances of a service\n * if this.component.multipleInstances is true.\n */\n get(identifier?: string): Promise {\n // if multipleInstances is not supported, use the default name\n const normalizedIdentifier = this.normalizeInstanceIdentifier(identifier);\n\n if (!this.instancesDeferred.has(normalizedIdentifier)) {\n const deferred = new Deferred();\n this.instancesDeferred.set(normalizedIdentifier, deferred);\n\n if (\n this.isInitialized(normalizedIdentifier) ||\n this.shouldAutoInitialize()\n ) {\n // initialize the service if it can be auto-initialized\n try {\n const instance = this.getOrInitializeService({\n instanceIdentifier: normalizedIdentifier\n });\n if (instance) {\n deferred.resolve(instance);\n }\n } catch (e) {\n // when the instance factory throws an exception during get(), it should not cause\n // a fatal error. We just return the unresolved promise in this case.\n }\n }\n }\n\n return this.instancesDeferred.get(normalizedIdentifier)!.promise;\n }\n\n /**\n *\n * @param options.identifier A provider can provide mulitple instances of a service\n * if this.component.multipleInstances is true.\n * @param options.optional If optional is false or not provided, the method throws an error when\n * the service is not immediately available.\n * If optional is true, the method returns null if the service is not immediately available.\n */\n getImmediate(options: {\n identifier?: string;\n optional: true;\n }): NameServiceMapping[T] | null;\n getImmediate(options?: {\n identifier?: string;\n optional?: false;\n }): NameServiceMapping[T];\n getImmediate(options?: {\n identifier?: string;\n optional?: boolean;\n }): NameServiceMapping[T] | null {\n // if multipleInstances is not supported, use the default name\n const normalizedIdentifier = this.normalizeInstanceIdentifier(\n options?.identifier\n );\n const optional = options?.optional ?? false;\n\n if (\n this.isInitialized(normalizedIdentifier) ||\n this.shouldAutoInitialize()\n ) {\n try {\n return this.getOrInitializeService({\n instanceIdentifier: normalizedIdentifier\n });\n } catch (e) {\n if (optional) {\n return null;\n } else {\n throw e;\n }\n }\n } else {\n // In case a component is not initialized and should/can not be auto-initialized at the moment, return null if the optional flag is set, or throw\n if (optional) {\n return null;\n } else {\n throw Error(`Service ${this.name} is not available`);\n }\n }\n }\n\n getComponent(): Component | null {\n return this.component;\n }\n\n setComponent(component: Component): void {\n if (component.name !== this.name) {\n throw Error(\n `Mismatching Component ${component.name} for Provider ${this.name}.`\n );\n }\n\n if (this.component) {\n throw Error(`Component for ${this.name} has already been provided`);\n }\n\n this.component = component;\n\n // return early without attempting to initialize the component if the component requires explicit initialization (calling `Provider.initialize()`)\n if (!this.shouldAutoInitialize()) {\n return;\n }\n\n // if the service is eager, initialize the default instance\n if (isComponentEager(component)) {\n try {\n this.getOrInitializeService({ instanceIdentifier: DEFAULT_ENTRY_NAME });\n } catch (e) {\n // when the instance factory for an eager Component throws an exception during the eager\n // initialization, it should not cause a fatal error.\n // TODO: Investigate if we need to make it configurable, because some component may want to cause\n // a fatal error in this case?\n }\n }\n\n // Create service instances for the pending promises and resolve them\n // NOTE: if this.multipleInstances is false, only the default instance will be created\n // and all promises with resolve with it regardless of the identifier.\n for (const [\n instanceIdentifier,\n instanceDeferred\n ] of this.instancesDeferred.entries()) {\n const normalizedIdentifier =\n this.normalizeInstanceIdentifier(instanceIdentifier);\n\n try {\n // `getOrInitializeService()` should always return a valid instance since a component is guaranteed. use ! to make typescript happy.\n const instance = this.getOrInitializeService({\n instanceIdentifier: normalizedIdentifier\n })!;\n instanceDeferred.resolve(instance);\n } catch (e) {\n // when the instance factory throws an exception, it should not cause\n // a fatal error. We just leave the promise unresolved.\n }\n }\n }\n\n clearInstance(identifier: string = DEFAULT_ENTRY_NAME): void {\n this.instancesDeferred.delete(identifier);\n this.instancesOptions.delete(identifier);\n this.instances.delete(identifier);\n }\n\n // app.delete() will call this method on every provider to delete the services\n // TODO: should we mark the provider as deleted?\n async delete(): Promise {\n const services = Array.from(this.instances.values());\n\n await Promise.all([\n ...services\n .filter(service => 'INTERNAL' in service) // legacy services\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n .map(service => (service as any).INTERNAL!.delete()),\n ...services\n .filter(service => '_delete' in service) // modularized services\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n .map(service => (service as any)._delete())\n ]);\n }\n\n isComponentSet(): boolean {\n return this.component != null;\n }\n\n isInitialized(identifier: string = DEFAULT_ENTRY_NAME): boolean {\n return this.instances.has(identifier);\n }\n\n getOptions(identifier: string = DEFAULT_ENTRY_NAME): Record {\n return this.instancesOptions.get(identifier) || {};\n }\n\n initialize(opts: InitializeOptions = {}): NameServiceMapping[T] {\n const { options = {} } = opts;\n const normalizedIdentifier = this.normalizeInstanceIdentifier(\n opts.instanceIdentifier\n );\n if (this.isInitialized(normalizedIdentifier)) {\n throw Error(\n `${this.name}(${normalizedIdentifier}) has already been initialized`\n );\n }\n\n if (!this.isComponentSet()) {\n throw Error(`Component ${this.name} has not been registered yet`);\n }\n\n const instance = this.getOrInitializeService({\n instanceIdentifier: normalizedIdentifier,\n options\n })!;\n\n // resolve any pending promise waiting for the service instance\n for (const [\n instanceIdentifier,\n instanceDeferred\n ] of this.instancesDeferred.entries()) {\n const normalizedDeferredIdentifier =\n this.normalizeInstanceIdentifier(instanceIdentifier);\n if (normalizedIdentifier === normalizedDeferredIdentifier) {\n instanceDeferred.resolve(instance);\n }\n }\n\n return instance;\n }\n\n /**\n *\n * @param callback - a function that will be invoked after the provider has been initialized by calling provider.initialize().\n * The function is invoked SYNCHRONOUSLY, so it should not execute any longrunning tasks in order to not block the program.\n *\n * @param identifier An optional instance identifier\n * @returns a function to unregister the callback\n */\n onInit(callback: OnInitCallBack, identifier?: string): () => void {\n const normalizedIdentifier = this.normalizeInstanceIdentifier(identifier);\n const existingCallbacks =\n this.onInitCallbacks.get(normalizedIdentifier) ??\n new Set>();\n existingCallbacks.add(callback);\n this.onInitCallbacks.set(normalizedIdentifier, existingCallbacks);\n\n const existingInstance = this.instances.get(normalizedIdentifier);\n if (existingInstance) {\n callback(existingInstance, normalizedIdentifier);\n }\n\n return () => {\n existingCallbacks.delete(callback);\n };\n }\n\n /**\n * Invoke onInit callbacks synchronously\n * @param instance the service instance`\n */\n private invokeOnInitCallbacks(\n instance: NameServiceMapping[T],\n identifier: string\n ): void {\n const callbacks = this.onInitCallbacks.get(identifier);\n if (!callbacks) {\n return;\n }\n for (const callback of callbacks) {\n try {\n callback(instance, identifier);\n } catch {\n // ignore errors in the onInit callback\n }\n }\n }\n\n private getOrInitializeService({\n instanceIdentifier,\n options = {}\n }: {\n instanceIdentifier: string;\n options?: Record;\n }): NameServiceMapping[T] | null {\n let instance = this.instances.get(instanceIdentifier);\n if (!instance && this.component) {\n instance = this.component.instanceFactory(this.container, {\n instanceIdentifier: normalizeIdentifierForFactory(instanceIdentifier),\n options\n });\n this.instances.set(instanceIdentifier, instance);\n this.instancesOptions.set(instanceIdentifier, options);\n\n /**\n * Invoke onInit listeners.\n * Note this.component.onInstanceCreated is different, which is used by the component creator,\n * while onInit listeners are registered by consumers of the provider.\n */\n this.invokeOnInitCallbacks(instance, instanceIdentifier);\n\n /**\n * Order is important\n * onInstanceCreated() should be called after this.instances.set(instanceIdentifier, instance); which\n * makes `isInitialized()` return true.\n */\n if (this.component.onInstanceCreated) {\n try {\n this.component.onInstanceCreated(\n this.container,\n instanceIdentifier,\n instance\n );\n } catch {\n // ignore errors in the onInstanceCreatedCallback\n }\n }\n }\n\n return instance || null;\n }\n\n private normalizeInstanceIdentifier(\n identifier: string = DEFAULT_ENTRY_NAME\n ): string {\n if (this.component) {\n return this.component.multipleInstances ? identifier : DEFAULT_ENTRY_NAME;\n } else {\n return identifier; // assume multiple instances are supported before the component is provided.\n }\n }\n\n private shouldAutoInitialize(): boolean {\n return (\n !!this.component &&\n this.component.instantiationMode !== InstantiationMode.EXPLICIT\n );\n }\n}\n\n// undefined should be passed to the service factory for the default instance\nfunction normalizeIdentifierForFactory(identifier: string): string | undefined {\n return identifier === DEFAULT_ENTRY_NAME ? undefined : identifier;\n}\n\nfunction isComponentEager(component: Component): boolean {\n return component.instantiationMode === InstantiationMode.EAGER;\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Provider } from './provider';\nimport { Component } from './component';\nimport { Name } from './types';\n\n/**\n * ComponentContainer that provides Providers for service name T, e.g. `auth`, `auth-internal`\n */\nexport class ComponentContainer {\n private readonly providers = new Map>();\n\n constructor(private readonly name: string) {}\n\n /**\n *\n * @param component Component being added\n * @param overwrite When a component with the same name has already been registered,\n * if overwrite is true: overwrite the existing component with the new component and create a new\n * provider with the new component. It can be useful in tests where you want to use different mocks\n * for different tests.\n * if overwrite is false: throw an exception\n */\n addComponent(component: Component): void {\n const provider = this.getProvider(component.name);\n if (provider.isComponentSet()) {\n throw new Error(\n `Component ${component.name} has already been registered with ${this.name}`\n );\n }\n\n provider.setComponent(component);\n }\n\n addOrOverwriteComponent(component: Component): void {\n const provider = this.getProvider(component.name);\n if (provider.isComponentSet()) {\n // delete the existing provider from the container, so we can register the new component\n this.providers.delete(component.name);\n }\n\n this.addComponent(component);\n }\n\n /**\n * getProvider provides a type safe interface where it can only be called with a field name\n * present in NameServiceMapping interface.\n *\n * Firebase SDKs providing services should extend NameServiceMapping interface to register\n * themselves.\n */\n getProvider(name: T): Provider {\n if (this.providers.has(name)) {\n return this.providers.get(name) as unknown as Provider;\n }\n\n // create a Provider for a service that hasn't registered with Firebase\n const provider = new Provider(name, this);\n this.providers.set(name, provider as unknown as Provider);\n\n return provider as Provider;\n }\n\n getProviders(): Array> {\n return Array.from(this.providers.values());\n }\n}\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport type LogLevelString =\n | 'debug'\n | 'verbose'\n | 'info'\n | 'warn'\n | 'error'\n | 'silent';\n\nexport interface LogOptions {\n level: LogLevelString;\n}\n\nexport type LogCallback = (callbackParams: LogCallbackParams) => void;\n\nexport interface LogCallbackParams {\n level: LogLevelString;\n message: string;\n args: unknown[];\n type: string;\n}\n\n/**\n * A container for all of the Logger instances\n */\nexport const instances: Logger[] = [];\n\n/**\n * The JS SDK supports 5 log levels and also allows a user the ability to\n * silence the logs altogether.\n *\n * The order is a follows:\n * DEBUG < VERBOSE < INFO < WARN < ERROR\n *\n * All of the log types above the current log level will be captured (i.e. if\n * you set the log level to `INFO`, errors will still be logged, but `DEBUG` and\n * `VERBOSE` logs will not)\n */\nexport enum LogLevel {\n DEBUG,\n VERBOSE,\n INFO,\n WARN,\n ERROR,\n SILENT\n}\n\nconst levelStringToEnum: { [key in LogLevelString]: LogLevel } = {\n 'debug': LogLevel.DEBUG,\n 'verbose': LogLevel.VERBOSE,\n 'info': LogLevel.INFO,\n 'warn': LogLevel.WARN,\n 'error': LogLevel.ERROR,\n 'silent': LogLevel.SILENT\n};\n\n/**\n * The default log level\n */\nconst defaultLogLevel: LogLevel = LogLevel.INFO;\n\n/**\n * We allow users the ability to pass their own log handler. We will pass the\n * type of log, the current log level, and any other arguments passed (i.e. the\n * messages that the user wants to log) to this function.\n */\nexport type LogHandler = (\n loggerInstance: Logger,\n logType: LogLevel,\n ...args: unknown[]\n) => void;\n\n/**\n * By default, `console.debug` is not displayed in the developer console (in\n * chrome). To avoid forcing users to have to opt-in to these logs twice\n * (i.e. once for firebase, and once in the console), we are sending `DEBUG`\n * logs to the `console.log` function.\n */\nconst ConsoleMethod = {\n [LogLevel.DEBUG]: 'log',\n [LogLevel.VERBOSE]: 'log',\n [LogLevel.INFO]: 'info',\n [LogLevel.WARN]: 'warn',\n [LogLevel.ERROR]: 'error'\n};\n\n/**\n * The default log handler will forward DEBUG, VERBOSE, INFO, WARN, and ERROR\n * messages on to their corresponding console counterparts (if the log method\n * is supported by the current log level)\n */\nconst defaultLogHandler: LogHandler = (instance, logType, ...args): void => {\n if (logType < instance.logLevel) {\n return;\n }\n const now = new Date().toISOString();\n const method = ConsoleMethod[logType as keyof typeof ConsoleMethod];\n if (method) {\n console[method as 'log' | 'info' | 'warn' | 'error'](\n `[${now}] ${instance.name}:`,\n ...args\n );\n } else {\n throw new Error(\n `Attempted to log a message with an invalid logType (value: ${logType})`\n );\n }\n};\n\nexport class Logger {\n /**\n * Gives you an instance of a Logger to capture messages according to\n * Firebase's logging scheme.\n *\n * @param name The name that the logs will be associated with\n */\n constructor(public name: string) {\n /**\n * Capture the current instance for later use\n */\n instances.push(this);\n }\n\n /**\n * The log level of the given Logger instance.\n */\n private _logLevel = defaultLogLevel;\n\n get logLevel(): LogLevel {\n return this._logLevel;\n }\n\n set logLevel(val: LogLevel) {\n if (!(val in LogLevel)) {\n throw new TypeError(`Invalid value \"${val}\" assigned to \\`logLevel\\``);\n }\n this._logLevel = val;\n }\n\n // Workaround for setter/getter having to be the same type.\n setLogLevel(val: LogLevel | LogLevelString): void {\n this._logLevel = typeof val === 'string' ? levelStringToEnum[val] : val;\n }\n\n /**\n * The main (internal) log handler for the Logger instance.\n * Can be set to a new function in internal package code but not by user.\n */\n private _logHandler: LogHandler = defaultLogHandler;\n get logHandler(): LogHandler {\n return this._logHandler;\n }\n set logHandler(val: LogHandler) {\n if (typeof val !== 'function') {\n throw new TypeError('Value assigned to `logHandler` must be a function');\n }\n this._logHandler = val;\n }\n\n /**\n * The optional, additional, user-defined log handler for the Logger instance.\n */\n private _userLogHandler: LogHandler | null = null;\n get userLogHandler(): LogHandler | null {\n return this._userLogHandler;\n }\n set userLogHandler(val: LogHandler | null) {\n this._userLogHandler = val;\n }\n\n /**\n * The functions below are all based on the `console` interface\n */\n\n debug(...args: unknown[]): void {\n this._userLogHandler && this._userLogHandler(this, LogLevel.DEBUG, ...args);\n this._logHandler(this, LogLevel.DEBUG, ...args);\n }\n log(...args: unknown[]): void {\n this._userLogHandler &&\n this._userLogHandler(this, LogLevel.VERBOSE, ...args);\n this._logHandler(this, LogLevel.VERBOSE, ...args);\n }\n info(...args: unknown[]): void {\n this._userLogHandler && this._userLogHandler(this, LogLevel.INFO, ...args);\n this._logHandler(this, LogLevel.INFO, ...args);\n }\n warn(...args: unknown[]): void {\n this._userLogHandler && this._userLogHandler(this, LogLevel.WARN, ...args);\n this._logHandler(this, LogLevel.WARN, ...args);\n }\n error(...args: unknown[]): void {\n this._userLogHandler && this._userLogHandler(this, LogLevel.ERROR, ...args);\n this._logHandler(this, LogLevel.ERROR, ...args);\n }\n}\n\nexport function setLogLevel(level: LogLevelString | LogLevel): void {\n instances.forEach(inst => {\n inst.setLogLevel(level);\n });\n}\n\nexport function setUserLogHandler(\n logCallback: LogCallback | null,\n options?: LogOptions\n): void {\n for (const instance of instances) {\n let customLogLevel: LogLevel | null = null;\n if (options && options.level) {\n customLogLevel = levelStringToEnum[options.level];\n }\n if (logCallback === null) {\n instance.userLogHandler = null;\n } else {\n instance.userLogHandler = (\n instance: Logger,\n level: LogLevel,\n ...args: unknown[]\n ) => {\n const message = args\n .map(arg => {\n if (arg == null) {\n return null;\n } else if (typeof arg === 'string') {\n return arg;\n } else if (typeof arg === 'number' || typeof arg === 'boolean') {\n return arg.toString();\n } else if (arg instanceof Error) {\n return arg.message;\n } else {\n try {\n return JSON.stringify(arg);\n } catch (ignored) {\n return null;\n }\n }\n })\n .filter(arg => arg)\n .join(' ');\n if (level >= (customLogLevel ?? instance.logLevel)) {\n logCallback({\n level: LogLevel[level].toLowerCase() as LogLevelString,\n message,\n args,\n type: instance.name\n });\n }\n };\n }\n }\n}\n", "const instanceOfAny = (object, constructors) => constructors.some((c) => object instanceof c);\n\nlet idbProxyableTypes;\nlet cursorAdvanceMethods;\n// This is a function to prevent it throwing up in node environments.\nfunction getIdbProxyableTypes() {\n return (idbProxyableTypes ||\n (idbProxyableTypes = [\n IDBDatabase,\n IDBObjectStore,\n IDBIndex,\n IDBCursor,\n IDBTransaction,\n ]));\n}\n// This is a function to prevent it throwing up in node environments.\nfunction getCursorAdvanceMethods() {\n return (cursorAdvanceMethods ||\n (cursorAdvanceMethods = [\n IDBCursor.prototype.advance,\n IDBCursor.prototype.continue,\n IDBCursor.prototype.continuePrimaryKey,\n ]));\n}\nconst cursorRequestMap = new WeakMap();\nconst transactionDoneMap = new WeakMap();\nconst transactionStoreNamesMap = new WeakMap();\nconst transformCache = new WeakMap();\nconst reverseTransformCache = new WeakMap();\nfunction promisifyRequest(request) {\n const promise = new Promise((resolve, reject) => {\n const unlisten = () => {\n request.removeEventListener('success', success);\n request.removeEventListener('error', error);\n };\n const success = () => {\n resolve(wrap(request.result));\n unlisten();\n };\n const error = () => {\n reject(request.error);\n unlisten();\n };\n request.addEventListener('success', success);\n request.addEventListener('error', error);\n });\n promise\n .then((value) => {\n // Since cursoring reuses the IDBRequest (*sigh*), we cache it for later retrieval\n // (see wrapFunction).\n if (value instanceof IDBCursor) {\n cursorRequestMap.set(value, request);\n }\n // Catching to avoid \"Uncaught Promise exceptions\"\n })\n .catch(() => { });\n // This mapping exists in reverseTransformCache but doesn't doesn't exist in transformCache. This\n // is because we create many promises from a single IDBRequest.\n reverseTransformCache.set(promise, request);\n return promise;\n}\nfunction cacheDonePromiseForTransaction(tx) {\n // Early bail if we've already created a done promise for this transaction.\n if (transactionDoneMap.has(tx))\n return;\n const done = new Promise((resolve, reject) => {\n const unlisten = () => {\n tx.removeEventListener('complete', complete);\n tx.removeEventListener('error', error);\n tx.removeEventListener('abort', error);\n };\n const complete = () => {\n resolve();\n unlisten();\n };\n const error = () => {\n reject(tx.error || new DOMException('AbortError', 'AbortError'));\n unlisten();\n };\n tx.addEventListener('complete', complete);\n tx.addEventListener('error', error);\n tx.addEventListener('abort', error);\n });\n // Cache it for later retrieval.\n transactionDoneMap.set(tx, done);\n}\nlet idbProxyTraps = {\n get(target, prop, receiver) {\n if (target instanceof IDBTransaction) {\n // Special handling for transaction.done.\n if (prop === 'done')\n return transactionDoneMap.get(target);\n // Polyfill for objectStoreNames because of Edge.\n if (prop === 'objectStoreNames') {\n return target.objectStoreNames || transactionStoreNamesMap.get(target);\n }\n // Make tx.store return the only store in the transaction, or undefined if there are many.\n if (prop === 'store') {\n return receiver.objectStoreNames[1]\n ? undefined\n : receiver.objectStore(receiver.objectStoreNames[0]);\n }\n }\n // Else transform whatever we get back.\n return wrap(target[prop]);\n },\n set(target, prop, value) {\n target[prop] = value;\n return true;\n },\n has(target, prop) {\n if (target instanceof IDBTransaction &&\n (prop === 'done' || prop === 'store')) {\n return true;\n }\n return prop in target;\n },\n};\nfunction replaceTraps(callback) {\n idbProxyTraps = callback(idbProxyTraps);\n}\nfunction wrapFunction(func) {\n // Due to expected object equality (which is enforced by the caching in `wrap`), we\n // only create one new func per func.\n // Edge doesn't support objectStoreNames (booo), so we polyfill it here.\n if (func === IDBDatabase.prototype.transaction &&\n !('objectStoreNames' in IDBTransaction.prototype)) {\n return function (storeNames, ...args) {\n const tx = func.call(unwrap(this), storeNames, ...args);\n transactionStoreNamesMap.set(tx, storeNames.sort ? storeNames.sort() : [storeNames]);\n return wrap(tx);\n };\n }\n // Cursor methods are special, as the behaviour is a little more different to standard IDB. In\n // IDB, you advance the cursor and wait for a new 'success' on the IDBRequest that gave you the\n // cursor. It's kinda like a promise that can resolve with many values. That doesn't make sense\n // with real promises, so each advance methods returns a new promise for the cursor object, or\n // undefined if the end of the cursor has been reached.\n if (getCursorAdvanceMethods().includes(func)) {\n return function (...args) {\n // Calling the original function with the proxy as 'this' causes ILLEGAL INVOCATION, so we use\n // the original object.\n func.apply(unwrap(this), args);\n return wrap(cursorRequestMap.get(this));\n };\n }\n return function (...args) {\n // Calling the original function with the proxy as 'this' causes ILLEGAL INVOCATION, so we use\n // the original object.\n return wrap(func.apply(unwrap(this), args));\n };\n}\nfunction transformCachableValue(value) {\n if (typeof value === 'function')\n return wrapFunction(value);\n // This doesn't return, it just creates a 'done' promise for the transaction,\n // which is later returned for transaction.done (see idbObjectHandler).\n if (value instanceof IDBTransaction)\n cacheDonePromiseForTransaction(value);\n if (instanceOfAny(value, getIdbProxyableTypes()))\n return new Proxy(value, idbProxyTraps);\n // Return the same value back if we're not going to transform it.\n return value;\n}\nfunction wrap(value) {\n // We sometimes generate multiple promises from a single IDBRequest (eg when cursoring), because\n // IDB is weird and a single IDBRequest can yield many responses, so these can't be cached.\n if (value instanceof IDBRequest)\n return promisifyRequest(value);\n // If we've already transformed this value before, reuse the transformed value.\n // This is faster, but it also provides object equality.\n if (transformCache.has(value))\n return transformCache.get(value);\n const newValue = transformCachableValue(value);\n // Not all types are transformed.\n // These may be primitive types, so they can't be WeakMap keys.\n if (newValue !== value) {\n transformCache.set(value, newValue);\n reverseTransformCache.set(newValue, value);\n }\n return newValue;\n}\nconst unwrap = (value) => reverseTransformCache.get(value);\n\nexport { reverseTransformCache as a, instanceOfAny as i, replaceTraps as r, unwrap as u, wrap as w };\n", "import { w as wrap, r as replaceTraps } from './wrap-idb-value.js';\nexport { u as unwrap, w as wrap } from './wrap-idb-value.js';\n\n/**\n * Open a database.\n *\n * @param name Name of the database.\n * @param version Schema version.\n * @param callbacks Additional callbacks.\n */\nfunction openDB(name, version, { blocked, upgrade, blocking, terminated } = {}) {\n const request = indexedDB.open(name, version);\n const openPromise = wrap(request);\n if (upgrade) {\n request.addEventListener('upgradeneeded', (event) => {\n upgrade(wrap(request.result), event.oldVersion, event.newVersion, wrap(request.transaction));\n });\n }\n if (blocked)\n request.addEventListener('blocked', () => blocked());\n openPromise\n .then((db) => {\n if (terminated)\n db.addEventListener('close', () => terminated());\n if (blocking)\n db.addEventListener('versionchange', () => blocking());\n })\n .catch(() => { });\n return openPromise;\n}\n/**\n * Delete a database.\n *\n * @param name Name of the database.\n */\nfunction deleteDB(name, { blocked } = {}) {\n const request = indexedDB.deleteDatabase(name);\n if (blocked)\n request.addEventListener('blocked', () => blocked());\n return wrap(request).then(() => undefined);\n}\n\nconst readMethods = ['get', 'getKey', 'getAll', 'getAllKeys', 'count'];\nconst writeMethods = ['put', 'add', 'delete', 'clear'];\nconst cachedMethods = new Map();\nfunction getMethod(target, prop) {\n if (!(target instanceof IDBDatabase &&\n !(prop in target) &&\n typeof prop === 'string')) {\n return;\n }\n if (cachedMethods.get(prop))\n return cachedMethods.get(prop);\n const targetFuncName = prop.replace(/FromIndex$/, '');\n const useIndex = prop !== targetFuncName;\n const isWrite = writeMethods.includes(targetFuncName);\n if (\n // Bail if the target doesn't exist on the target. Eg, getAll isn't in Edge.\n !(targetFuncName in (useIndex ? IDBIndex : IDBObjectStore).prototype) ||\n !(isWrite || readMethods.includes(targetFuncName))) {\n return;\n }\n const method = async function (storeName, ...args) {\n // isWrite ? 'readwrite' : undefined gzipps better, but fails in Edge :(\n const tx = this.transaction(storeName, isWrite ? 'readwrite' : 'readonly');\n let target = tx.store;\n if (useIndex)\n target = target.index(args.shift());\n // Must reject if op rejects.\n // If it's a write operation, must reject if tx.done rejects.\n // Must reject with op rejection first.\n // Must resolve with op value.\n // Must handle both promises (no unhandled rejections)\n return (await Promise.all([\n target[targetFuncName](...args),\n isWrite && tx.done,\n ]))[0];\n };\n cachedMethods.set(prop, method);\n return method;\n}\nreplaceTraps((oldTraps) => ({\n ...oldTraps,\n get: (target, prop, receiver) => getMethod(target, prop) || oldTraps.get(target, prop, receiver),\n has: (target, prop) => !!getMethod(target, prop) || oldTraps.has(target, prop),\n}));\n\nexport { deleteDB, openDB };\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n ComponentContainer,\n ComponentType,\n Provider,\n Name\n} from '@firebase/component';\nimport { PlatformLoggerService, VersionService } from './types';\n\nexport class PlatformLoggerServiceImpl implements PlatformLoggerService {\n constructor(private readonly container: ComponentContainer) {}\n // In initial implementation, this will be called by installations on\n // auth token refresh, and installations will send this string.\n getPlatformInfoString(): string {\n const providers = this.container.getProviders();\n // Loop through providers and get library/version pairs from any that are\n // version components.\n return providers\n .map(provider => {\n if (isVersionServiceProvider(provider)) {\n const service = provider.getImmediate() as VersionService;\n return `${service.library}/${service.version}`;\n } else {\n return null;\n }\n })\n .filter(logString => logString)\n .join(' ');\n }\n}\n/**\n *\n * @param provider check if this provider provides a VersionService\n *\n * NOTE: Using Provider<'app-version'> is a hack to indicate that the provider\n * provides VersionService. The provider is not necessarily a 'app-version'\n * provider.\n */\nfunction isVersionServiceProvider(provider: Provider): boolean {\n const component = provider.getComponent();\n return component?.type === ComponentType.VERSION;\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Logger } from '@firebase/logger';\n\nexport const logger = new Logger('@firebase/app');\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { name as appName } from '../package.json';\nimport { name as appCompatName } from '../../app-compat/package.json';\nimport { name as analyticsCompatName } from '../../../packages/analytics-compat/package.json';\nimport { name as analyticsName } from '../../../packages/analytics/package.json';\nimport { name as appCheckCompatName } from '../../../packages/app-check-compat/package.json';\nimport { name as appCheckName } from '../../../packages/app-check/package.json';\nimport { name as authName } from '../../../packages/auth/package.json';\nimport { name as authCompatName } from '../../../packages/auth-compat/package.json';\nimport { name as databaseName } from '../../../packages/database/package.json';\nimport { name as databaseCompatName } from '../../../packages/database-compat/package.json';\nimport { name as functionsName } from '../../../packages/functions/package.json';\nimport { name as functionsCompatName } from '../../../packages/functions-compat/package.json';\nimport { name as installationsName } from '../../../packages/installations/package.json';\nimport { name as installationsCompatName } from '../../../packages/installations-compat/package.json';\nimport { name as messagingName } from '../../../packages/messaging/package.json';\nimport { name as messagingCompatName } from '../../../packages/messaging-compat/package.json';\nimport { name as performanceName } from '../../../packages/performance/package.json';\nimport { name as performanceCompatName } from '../../../packages/performance-compat/package.json';\nimport { name as remoteConfigName } from '../../../packages/remote-config/package.json';\nimport { name as remoteConfigCompatName } from '../../../packages/remote-config-compat/package.json';\nimport { name as storageName } from '../../../packages/storage/package.json';\nimport { name as storageCompatName } from '../../../packages/storage-compat/package.json';\nimport { name as firestoreName } from '../../../packages/firestore/package.json';\nimport { name as firestoreCompatName } from '../../../packages/firestore-compat/package.json';\nimport { name as packageName } from '../../../packages/firebase/package.json';\n\n/**\n * The default app name\n *\n * @internal\n */\nexport const DEFAULT_ENTRY_NAME = '[DEFAULT]';\n\nexport const PLATFORM_LOG_STRING = {\n [appName]: 'fire-core',\n [appCompatName]: 'fire-core-compat',\n [analyticsName]: 'fire-analytics',\n [analyticsCompatName]: 'fire-analytics-compat',\n [appCheckName]: 'fire-app-check',\n [appCheckCompatName]: 'fire-app-check-compat',\n [authName]: 'fire-auth',\n [authCompatName]: 'fire-auth-compat',\n [databaseName]: 'fire-rtdb',\n [databaseCompatName]: 'fire-rtdb-compat',\n [functionsName]: 'fire-fn',\n [functionsCompatName]: 'fire-fn-compat',\n [installationsName]: 'fire-iid',\n [installationsCompatName]: 'fire-iid-compat',\n [messagingName]: 'fire-fcm',\n [messagingCompatName]: 'fire-fcm-compat',\n [performanceName]: 'fire-perf',\n [performanceCompatName]: 'fire-perf-compat',\n [remoteConfigName]: 'fire-rc',\n [remoteConfigCompatName]: 'fire-rc-compat',\n [storageName]: 'fire-gcs',\n [storageCompatName]: 'fire-gcs-compat',\n [firestoreName]: 'fire-fst',\n [firestoreCompatName]: 'fire-fst-compat',\n 'fire-js': 'fire-js', // Platform identifier for JS SDK.\n [packageName]: 'fire-js-all'\n} as const;\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { FirebaseApp } from './public-types';\nimport { Component, Provider, Name } from '@firebase/component';\nimport { logger } from './logger';\nimport { DEFAULT_ENTRY_NAME } from './constants';\nimport { FirebaseAppImpl } from './firebaseApp';\n\n/**\n * @internal\n */\nexport const _apps = new Map();\n\n/**\n * Registered components.\n *\n * @internal\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport const _components = new Map>();\n\n/**\n * @param component - the component being added to this app's container\n *\n * @internal\n */\nexport function _addComponent(\n app: FirebaseApp,\n component: Component\n): void {\n try {\n (app as FirebaseAppImpl).container.addComponent(component);\n } catch (e) {\n logger.debug(\n `Component ${component.name} failed to register with FirebaseApp ${app.name}`,\n e\n );\n }\n}\n\n/**\n *\n * @internal\n */\nexport function _addOrOverwriteComponent(\n app: FirebaseApp,\n component: Component\n): void {\n (app as FirebaseAppImpl).container.addOrOverwriteComponent(component);\n}\n\n/**\n *\n * @param component - the component to register\n * @returns whether or not the component is registered successfully\n *\n * @internal\n */\nexport function _registerComponent(\n component: Component\n): boolean {\n const componentName = component.name;\n if (_components.has(componentName)) {\n logger.debug(\n `There were multiple attempts to register component ${componentName}.`\n );\n\n return false;\n }\n\n _components.set(componentName, component);\n\n // add the component to existing app instances\n for (const app of _apps.values()) {\n _addComponent(app as FirebaseAppImpl, component);\n }\n\n return true;\n}\n\n/**\n *\n * @param app - FirebaseApp instance\n * @param name - service name\n *\n * @returns the provider for the service with the matching name\n *\n * @internal\n */\nexport function _getProvider(\n app: FirebaseApp,\n name: T\n): Provider {\n const heartbeatController = (app as FirebaseAppImpl).container\n .getProvider('heartbeat')\n .getImmediate({ optional: true });\n if (heartbeatController) {\n void heartbeatController.triggerHeartbeat();\n }\n return (app as FirebaseAppImpl).container.getProvider(name);\n}\n\n/**\n *\n * @param app - FirebaseApp instance\n * @param name - service name\n * @param instanceIdentifier - service instance identifier in case the service supports multiple instances\n *\n * @internal\n */\nexport function _removeServiceInstance(\n app: FirebaseApp,\n name: T,\n instanceIdentifier: string = DEFAULT_ENTRY_NAME\n): void {\n _getProvider(app, name).clearInstance(instanceIdentifier);\n}\n\n/**\n * Test only\n *\n * @internal\n */\nexport function _clearComponents(): void {\n _components.clear();\n}\n\n/**\n * Exported in order to be used in app-compat package\n */\nexport { DEFAULT_ENTRY_NAME as _DEFAULT_ENTRY_NAME };\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ErrorFactory, ErrorMap } from '@firebase/util';\n\nexport const enum AppError {\n NO_APP = 'no-app',\n BAD_APP_NAME = 'bad-app-name',\n DUPLICATE_APP = 'duplicate-app',\n APP_DELETED = 'app-deleted',\n INVALID_APP_ARGUMENT = 'invalid-app-argument',\n INVALID_LOG_ARGUMENT = 'invalid-log-argument',\n IDB_OPEN = 'idb-open',\n IDB_GET = 'idb-get',\n IDB_WRITE = 'idb-set',\n IDB_DELETE = 'idb-delete'\n}\n\nconst ERRORS: ErrorMap = {\n [AppError.NO_APP]:\n \"No Firebase App '{$appName}' has been created - \" +\n 'call Firebase App.initializeApp()',\n [AppError.BAD_APP_NAME]: \"Illegal App name: '{$appName}\",\n [AppError.DUPLICATE_APP]:\n \"Firebase App named '{$appName}' already exists with different options or config\",\n [AppError.APP_DELETED]: \"Firebase App named '{$appName}' already deleted\",\n [AppError.INVALID_APP_ARGUMENT]:\n 'firebase.{$appName}() takes either no argument or a ' +\n 'Firebase App instance.',\n [AppError.INVALID_LOG_ARGUMENT]:\n 'First argument to `onLog` must be null or a function.',\n [AppError.IDB_OPEN]:\n 'Error thrown when opening IndexedDB. Original error: {$originalErrorMessage}.',\n [AppError.IDB_GET]:\n 'Error thrown when reading from IndexedDB. Original error: {$originalErrorMessage}.',\n [AppError.IDB_WRITE]:\n 'Error thrown when writing to IndexedDB. Original error: {$originalErrorMessage}.',\n [AppError.IDB_DELETE]:\n 'Error thrown when deleting from IndexedDB. Original error: {$originalErrorMessage}.'\n};\n\ninterface ErrorParams {\n [AppError.NO_APP]: { appName: string };\n [AppError.BAD_APP_NAME]: { appName: string };\n [AppError.DUPLICATE_APP]: { appName: string };\n [AppError.APP_DELETED]: { appName: string };\n [AppError.INVALID_APP_ARGUMENT]: { appName: string };\n [AppError.IDB_OPEN]: { originalErrorMessage?: string };\n [AppError.IDB_GET]: { originalErrorMessage?: string };\n [AppError.IDB_WRITE]: { originalErrorMessage?: string };\n [AppError.IDB_DELETE]: { originalErrorMessage?: string };\n}\n\nexport const ERROR_FACTORY = new ErrorFactory(\n 'app',\n 'Firebase',\n ERRORS\n);\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n FirebaseApp,\n FirebaseOptions,\n FirebaseAppSettings\n} from './public-types';\nimport {\n ComponentContainer,\n Component,\n ComponentType\n} from '@firebase/component';\nimport { ERROR_FACTORY, AppError } from './errors';\n\nexport class FirebaseAppImpl implements FirebaseApp {\n private readonly _options: FirebaseOptions;\n private readonly _name: string;\n /**\n * Original config values passed in as a constructor parameter.\n * It is only used to compare with another config object to support idempotent initializeApp().\n *\n * Updating automaticDataCollectionEnabled on the App instance will not change its value in _config.\n */\n private readonly _config: Required;\n private _automaticDataCollectionEnabled: boolean;\n private _isDeleted = false;\n private readonly _container: ComponentContainer;\n\n constructor(\n options: FirebaseOptions,\n config: Required,\n container: ComponentContainer\n ) {\n this._options = { ...options };\n this._config = { ...config };\n this._name = config.name;\n this._automaticDataCollectionEnabled =\n config.automaticDataCollectionEnabled;\n this._container = container;\n this.container.addComponent(\n new Component('app', () => this, ComponentType.PUBLIC)\n );\n }\n\n get automaticDataCollectionEnabled(): boolean {\n this.checkDestroyed();\n return this._automaticDataCollectionEnabled;\n }\n\n set automaticDataCollectionEnabled(val: boolean) {\n this.checkDestroyed();\n this._automaticDataCollectionEnabled = val;\n }\n\n get name(): string {\n this.checkDestroyed();\n return this._name;\n }\n\n get options(): FirebaseOptions {\n this.checkDestroyed();\n return this._options;\n }\n\n get config(): Required {\n this.checkDestroyed();\n return this._config;\n }\n\n get container(): ComponentContainer {\n return this._container;\n }\n\n get isDeleted(): boolean {\n return this._isDeleted;\n }\n\n set isDeleted(val: boolean) {\n this._isDeleted = val;\n }\n\n /**\n * This function will throw an Error if the App has already been deleted -\n * use before performing API actions on the App.\n */\n private checkDestroyed(): void {\n if (this.isDeleted) {\n throw ERROR_FACTORY.create(AppError.APP_DELETED, { appName: this._name });\n }\n }\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n FirebaseApp,\n FirebaseOptions,\n FirebaseAppSettings\n} from './public-types';\nimport { DEFAULT_ENTRY_NAME, PLATFORM_LOG_STRING } from './constants';\nimport { ERROR_FACTORY, AppError } from './errors';\nimport {\n ComponentContainer,\n Component,\n Name,\n ComponentType\n} from '@firebase/component';\nimport { version } from '../../firebase/package.json';\nimport { FirebaseAppImpl } from './firebaseApp';\nimport { _apps, _components, _registerComponent } from './internal';\nimport { logger } from './logger';\nimport {\n LogLevelString,\n setLogLevel as setLogLevelImpl,\n LogCallback,\n LogOptions,\n setUserLogHandler\n} from '@firebase/logger';\nimport { deepEqual } from '@firebase/util';\n\nexport { FirebaseError } from '@firebase/util';\n\n/**\n * The current SDK version.\n *\n * @public\n */\nexport const SDK_VERSION = version;\n\n/**\n * Creates and initializes a {@link @firebase/app#FirebaseApp} instance.\n *\n * See\n * {@link\n * https://firebase.google.com/docs/web/setup#add_firebase_to_your_app\n * | Add Firebase to your app} and\n * {@link\n * https://firebase.google.com/docs/web/setup#multiple-projects\n * | Initialize multiple projects} for detailed documentation.\n *\n * @example\n * ```javascript\n *\n * // Initialize default app\n * // Retrieve your own options values by adding a web app on\n * // https://console.firebase.google.com\n * initializeApp({\n * apiKey: \"AIza....\", // Auth / General Use\n * authDomain: \"YOUR_APP.firebaseapp.com\", // Auth with popup/redirect\n * databaseURL: \"https://YOUR_APP.firebaseio.com\", // Realtime Database\n * storageBucket: \"YOUR_APP.appspot.com\", // Storage\n * messagingSenderId: \"123456789\" // Cloud Messaging\n * });\n * ```\n *\n * @example\n * ```javascript\n *\n * // Initialize another app\n * const otherApp = initializeApp({\n * databaseURL: \"https://.firebaseio.com\",\n * storageBucket: \".appspot.com\"\n * }, \"otherApp\");\n * ```\n *\n * @param options - Options to configure the app's services.\n * @param name - Optional name of the app to initialize. If no name\n * is provided, the default is `\"[DEFAULT]\"`.\n *\n * @returns The initialized app.\n *\n * @public\n */\nexport function initializeApp(\n options: FirebaseOptions,\n name?: string\n): FirebaseApp;\n/**\n * Creates and initializes a FirebaseApp instance.\n *\n * @param options - Options to configure the app's services.\n * @param config - FirebaseApp Configuration\n *\n * @public\n */\nexport function initializeApp(\n options: FirebaseOptions,\n config?: FirebaseAppSettings\n): FirebaseApp;\nexport function initializeApp(\n options: FirebaseOptions,\n rawConfig = {}\n): FirebaseApp {\n if (typeof rawConfig !== 'object') {\n const name = rawConfig;\n rawConfig = { name };\n }\n\n const config: Required = {\n name: DEFAULT_ENTRY_NAME,\n automaticDataCollectionEnabled: false,\n ...rawConfig\n };\n const name = config.name;\n\n if (typeof name !== 'string' || !name) {\n throw ERROR_FACTORY.create(AppError.BAD_APP_NAME, {\n appName: String(name)\n });\n }\n\n const existingApp = _apps.get(name) as FirebaseAppImpl;\n if (existingApp) {\n // return the existing app if options and config deep equal the ones in the existing app.\n if (\n deepEqual(options, existingApp.options) &&\n deepEqual(config, existingApp.config)\n ) {\n return existingApp;\n } else {\n throw ERROR_FACTORY.create(AppError.DUPLICATE_APP, { appName: name });\n }\n }\n\n const container = new ComponentContainer(name);\n for (const component of _components.values()) {\n container.addComponent(component);\n }\n\n const newApp = new FirebaseAppImpl(options, config, container);\n\n _apps.set(name, newApp);\n\n return newApp;\n}\n\n/**\n * Retrieves a {@link @firebase/app#FirebaseApp} instance.\n *\n * When called with no arguments, the default app is returned. When an app name\n * is provided, the app corresponding to that name is returned.\n *\n * An exception is thrown if the app being retrieved has not yet been\n * initialized.\n *\n * @example\n * ```javascript\n * // Return the default app\n * const app = getApp();\n * ```\n *\n * @example\n * ```javascript\n * // Return a named app\n * const otherApp = getApp(\"otherApp\");\n * ```\n *\n * @param name - Optional name of the app to return. If no name is\n * provided, the default is `\"[DEFAULT]\"`.\n *\n * @returns The app corresponding to the provided app name.\n * If no app name is provided, the default app is returned.\n *\n * @public\n */\nexport function getApp(name: string = DEFAULT_ENTRY_NAME): FirebaseApp {\n const app = _apps.get(name);\n if (!app) {\n throw ERROR_FACTORY.create(AppError.NO_APP, { appName: name });\n }\n\n return app;\n}\n\n/**\n * A (read-only) array of all initialized apps.\n * @public\n */\nexport function getApps(): FirebaseApp[] {\n return Array.from(_apps.values());\n}\n\n/**\n * Renders this app unusable and frees the resources of all associated\n * services.\n *\n * @example\n * ```javascript\n * deleteApp(app)\n * .then(function() {\n * console.log(\"App deleted successfully\");\n * })\n * .catch(function(error) {\n * console.log(\"Error deleting app:\", error);\n * });\n * ```\n *\n * @public\n */\nexport async function deleteApp(app: FirebaseApp): Promise {\n const name = app.name;\n if (_apps.has(name)) {\n _apps.delete(name);\n await Promise.all(\n (app as FirebaseAppImpl).container\n .getProviders()\n .map(provider => provider.delete())\n );\n (app as FirebaseAppImpl).isDeleted = true;\n }\n}\n\n/**\n * Registers a library's name and version for platform logging purposes.\n * @param library - Name of 1p or 3p library (e.g. firestore, angularfire)\n * @param version - Current version of that library.\n * @param variant - Bundle variant, e.g., node, rn, etc.\n *\n * @public\n */\nexport function registerVersion(\n libraryKeyOrName: string,\n version: string,\n variant?: string\n): void {\n // TODO: We can use this check to whitelist strings when/if we set up\n // a good whitelist system.\n let library = PLATFORM_LOG_STRING[libraryKeyOrName] ?? libraryKeyOrName;\n if (variant) {\n library += `-${variant}`;\n }\n const libraryMismatch = library.match(/\\s|\\//);\n const versionMismatch = version.match(/\\s|\\//);\n if (libraryMismatch || versionMismatch) {\n const warning = [\n `Unable to register library \"${library}\" with version \"${version}\":`\n ];\n if (libraryMismatch) {\n warning.push(\n `library name \"${library}\" contains illegal characters (whitespace or \"/\")`\n );\n }\n if (libraryMismatch && versionMismatch) {\n warning.push('and');\n }\n if (versionMismatch) {\n warning.push(\n `version name \"${version}\" contains illegal characters (whitespace or \"/\")`\n );\n }\n logger.warn(warning.join(' '));\n return;\n }\n _registerComponent(\n new Component(\n `${library}-version` as Name,\n () => ({ library, version }),\n ComponentType.VERSION\n )\n );\n}\n\n/**\n * Sets log handler for all Firebase SDKs.\n * @param logCallback - An optional custom log handler that executes user code whenever\n * the Firebase SDK makes a logging call.\n *\n * @public\n */\nexport function onLog(\n logCallback: LogCallback | null,\n options?: LogOptions\n): void {\n if (logCallback !== null && typeof logCallback !== 'function') {\n throw ERROR_FACTORY.create(AppError.INVALID_LOG_ARGUMENT);\n }\n setUserLogHandler(logCallback, options);\n}\n\n/**\n * Sets log level for all Firebase SDKs.\n *\n * All of the log types above the current log level are captured (i.e. if\n * you set the log level to `info`, errors are logged, but `debug` and\n * `verbose` logs are not).\n *\n * @public\n */\nexport function setLogLevel(logLevel: LogLevelString): void {\n setLogLevelImpl(logLevel);\n}\n", "/**\n * @license\n * Copyright 2021 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { FirebaseError } from '@firebase/util';\nimport { DBSchema, openDB, IDBPDatabase } from 'idb';\nimport { AppError, ERROR_FACTORY } from './errors';\nimport { FirebaseApp } from './public-types';\nimport { HeartbeatsInIndexedDB } from './types';\nimport { logger } from './logger';\n\nconst DB_NAME = 'firebase-heartbeat-database';\nconst DB_VERSION = 1;\nconst STORE_NAME = 'firebase-heartbeat-store';\n\ninterface AppDB extends DBSchema {\n 'firebase-heartbeat-store': {\n key: string;\n value: HeartbeatsInIndexedDB;\n };\n}\n\nlet dbPromise: Promise> | null = null;\nfunction getDbPromise(): Promise> {\n if (!dbPromise) {\n dbPromise = openDB(DB_NAME, DB_VERSION, {\n upgrade: (db, oldVersion) => {\n // We don't use 'break' in this switch statement, the fall-through\n // behavior is what we want, because if there are multiple versions between\n // the old version and the current version, we want ALL the migrations\n // that correspond to those versions to run, not only the last one.\n // eslint-disable-next-line default-case\n switch (oldVersion) {\n case 0:\n db.createObjectStore(STORE_NAME);\n }\n }\n }).catch(e => {\n throw ERROR_FACTORY.create(AppError.IDB_OPEN, {\n originalErrorMessage: e.message\n });\n });\n }\n return dbPromise;\n}\n\nexport async function readHeartbeatsFromIndexedDB(\n app: FirebaseApp\n): Promise {\n try {\n const db = await getDbPromise();\n return db\n .transaction(STORE_NAME)\n .objectStore(STORE_NAME)\n .get(computeKey(app)) as Promise;\n } catch (e) {\n if (e instanceof FirebaseError) {\n logger.warn(e.message);\n } else {\n const idbGetError = ERROR_FACTORY.create(AppError.IDB_GET, {\n originalErrorMessage: (e as Error)?.message\n });\n logger.warn(idbGetError.message);\n }\n }\n}\n\nexport async function writeHeartbeatsToIndexedDB(\n app: FirebaseApp,\n heartbeatObject: HeartbeatsInIndexedDB\n): Promise {\n try {\n const db = await getDbPromise();\n const tx = db.transaction(STORE_NAME, 'readwrite');\n const objectStore = tx.objectStore(STORE_NAME);\n await objectStore.put(heartbeatObject, computeKey(app));\n return tx.done;\n } catch (e) {\n if (e instanceof FirebaseError) {\n logger.warn(e.message);\n } else {\n const idbGetError = ERROR_FACTORY.create(AppError.IDB_WRITE, {\n originalErrorMessage: (e as Error)?.message\n });\n logger.warn(idbGetError.message);\n }\n }\n}\n\nfunction computeKey(app: FirebaseApp): string {\n return `${app.name}!${app.options.appId}`;\n}\n", "/**\n * @license\n * Copyright 2021 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ComponentContainer } from '@firebase/component';\nimport {\n base64urlEncodeWithoutPadding,\n isIndexedDBAvailable,\n validateIndexedDBOpenable\n} from '@firebase/util';\nimport {\n readHeartbeatsFromIndexedDB,\n writeHeartbeatsToIndexedDB\n} from './indexeddb';\nimport { FirebaseApp } from './public-types';\nimport {\n HeartbeatsByUserAgent,\n HeartbeatService,\n HeartbeatsInIndexedDB,\n HeartbeatStorage,\n SingleDateHeartbeat\n} from './types';\n\nconst MAX_HEADER_BYTES = 1024;\n// 30 days\nconst STORED_HEARTBEAT_RETENTION_MAX_MILLIS = 30 * 24 * 60 * 60 * 1000;\n\nexport class HeartbeatServiceImpl implements HeartbeatService {\n /**\n * The persistence layer for heartbeats\n * Leave public for easier testing.\n */\n _storage: HeartbeatStorageImpl;\n\n /**\n * In-memory cache for heartbeats, used by getHeartbeatsHeader() to generate\n * the header string.\n * Stores one record per date. This will be consolidated into the standard\n * format of one record per user agent string before being sent as a header.\n * Populated from indexedDB when the controller is instantiated and should\n * be kept in sync with indexedDB.\n * Leave public for easier testing.\n */\n _heartbeatsCache: HeartbeatsInIndexedDB | null = null;\n\n /**\n * the initialization promise for populating heartbeatCache.\n * If getHeartbeatsHeader() is called before the promise resolves\n * (hearbeatsCache == null), it should wait for this promise\n * Leave public for easier testing.\n */\n _heartbeatsCachePromise: Promise;\n constructor(private readonly container: ComponentContainer) {\n const app = this.container.getProvider('app').getImmediate();\n this._storage = new HeartbeatStorageImpl(app);\n this._heartbeatsCachePromise = this._storage.read().then(result => {\n this._heartbeatsCache = result;\n return result;\n });\n }\n\n /**\n * Called to report a heartbeat. The function will generate\n * a HeartbeatsByUserAgent object, update heartbeatsCache, and persist it\n * to IndexedDB.\n * Note that we only store one heartbeat per day. So if a heartbeat for today is\n * already logged, subsequent calls to this function in the same day will be ignored.\n */\n async triggerHeartbeat(): Promise {\n const platformLogger = this.container\n .getProvider('platform-logger')\n .getImmediate();\n\n // This is the \"Firebase user agent\" string from the platform logger\n // service, not the browser user agent.\n const agent = platformLogger.getPlatformInfoString();\n const date = getUTCDateString();\n if (this._heartbeatsCache === null) {\n this._heartbeatsCache = await this._heartbeatsCachePromise;\n }\n // Do not store a heartbeat if one is already stored for this day\n // or if a header has already been sent today.\n if (\n this._heartbeatsCache.lastSentHeartbeatDate === date ||\n this._heartbeatsCache.heartbeats.some(\n singleDateHeartbeat => singleDateHeartbeat.date === date\n )\n ) {\n return;\n } else {\n // There is no entry for this date. Create one.\n this._heartbeatsCache.heartbeats.push({ date, agent });\n }\n // Remove entries older than 30 days.\n this._heartbeatsCache.heartbeats = this._heartbeatsCache.heartbeats.filter(\n singleDateHeartbeat => {\n const hbTimestamp = new Date(singleDateHeartbeat.date).valueOf();\n const now = Date.now();\n return now - hbTimestamp <= STORED_HEARTBEAT_RETENTION_MAX_MILLIS;\n }\n );\n return this._storage.overwrite(this._heartbeatsCache);\n }\n\n /**\n * Returns a base64 encoded string which can be attached to the heartbeat-specific header directly.\n * It also clears all heartbeats from memory as well as in IndexedDB.\n *\n * NOTE: Consuming product SDKs should not send the header if this method\n * returns an empty string.\n */\n async getHeartbeatsHeader(): Promise {\n if (this._heartbeatsCache === null) {\n await this._heartbeatsCachePromise;\n }\n // If it's still null or the array is empty, there is no data to send.\n if (\n this._heartbeatsCache === null ||\n this._heartbeatsCache.heartbeats.length === 0\n ) {\n return '';\n }\n const date = getUTCDateString();\n // Extract as many heartbeats from the cache as will fit under the size limit.\n const { heartbeatsToSend, unsentEntries } = extractHeartbeatsForHeader(\n this._heartbeatsCache.heartbeats\n );\n const headerString = base64urlEncodeWithoutPadding(\n JSON.stringify({ version: 2, heartbeats: heartbeatsToSend })\n );\n // Store last sent date to prevent another being logged/sent for the same day.\n this._heartbeatsCache.lastSentHeartbeatDate = date;\n if (unsentEntries.length > 0) {\n // Store any unsent entries if they exist.\n this._heartbeatsCache.heartbeats = unsentEntries;\n // This seems more likely than emptying the array (below) to lead to some odd state\n // since the cache isn't empty and this will be called again on the next request,\n // and is probably safest if we await it.\n await this._storage.overwrite(this._heartbeatsCache);\n } else {\n this._heartbeatsCache.heartbeats = [];\n // Do not wait for this, to reduce latency.\n void this._storage.overwrite(this._heartbeatsCache);\n }\n return headerString;\n }\n}\n\nfunction getUTCDateString(): string {\n const today = new Date();\n // Returns date format 'YYYY-MM-DD'\n return today.toISOString().substring(0, 10);\n}\n\nexport function extractHeartbeatsForHeader(\n heartbeatsCache: SingleDateHeartbeat[],\n maxSize = MAX_HEADER_BYTES\n): {\n heartbeatsToSend: HeartbeatsByUserAgent[];\n unsentEntries: SingleDateHeartbeat[];\n} {\n // Heartbeats grouped by user agent in the standard format to be sent in\n // the header.\n const heartbeatsToSend: HeartbeatsByUserAgent[] = [];\n // Single date format heartbeats that are not sent.\n let unsentEntries = heartbeatsCache.slice();\n for (const singleDateHeartbeat of heartbeatsCache) {\n // Look for an existing entry with the same user agent.\n const heartbeatEntry = heartbeatsToSend.find(\n hb => hb.agent === singleDateHeartbeat.agent\n );\n if (!heartbeatEntry) {\n // If no entry for this user agent exists, create one.\n heartbeatsToSend.push({\n agent: singleDateHeartbeat.agent,\n dates: [singleDateHeartbeat.date]\n });\n if (countBytes(heartbeatsToSend) > maxSize) {\n // If the header would exceed max size, remove the added heartbeat\n // entry and stop adding to the header.\n heartbeatsToSend.pop();\n break;\n }\n } else {\n heartbeatEntry.dates.push(singleDateHeartbeat.date);\n // If the header would exceed max size, remove the added date\n // and stop adding to the header.\n if (countBytes(heartbeatsToSend) > maxSize) {\n heartbeatEntry.dates.pop();\n break;\n }\n }\n // Pop unsent entry from queue. (Skipped if adding the entry exceeded\n // quota and the loop breaks early.)\n unsentEntries = unsentEntries.slice(1);\n }\n return {\n heartbeatsToSend,\n unsentEntries\n };\n}\n\nexport class HeartbeatStorageImpl implements HeartbeatStorage {\n private _canUseIndexedDBPromise: Promise;\n constructor(public app: FirebaseApp) {\n this._canUseIndexedDBPromise = this.runIndexedDBEnvironmentCheck();\n }\n async runIndexedDBEnvironmentCheck(): Promise {\n if (!isIndexedDBAvailable()) {\n return false;\n } else {\n return validateIndexedDBOpenable()\n .then(() => true)\n .catch(() => false);\n }\n }\n /**\n * Read all heartbeats.\n */\n async read(): Promise {\n const canUseIndexedDB = await this._canUseIndexedDBPromise;\n if (!canUseIndexedDB) {\n return { heartbeats: [] };\n } else {\n const idbHeartbeatObject = await readHeartbeatsFromIndexedDB(this.app);\n return idbHeartbeatObject || { heartbeats: [] };\n }\n }\n // overwrite the storage with the provided heartbeats\n async overwrite(heartbeatsObject: HeartbeatsInIndexedDB): Promise {\n const canUseIndexedDB = await this._canUseIndexedDBPromise;\n if (!canUseIndexedDB) {\n return;\n } else {\n const existingHeartbeatsObject = await this.read();\n return writeHeartbeatsToIndexedDB(this.app, {\n lastSentHeartbeatDate:\n heartbeatsObject.lastSentHeartbeatDate ??\n existingHeartbeatsObject.lastSentHeartbeatDate,\n heartbeats: heartbeatsObject.heartbeats\n });\n }\n }\n // add heartbeats\n async add(heartbeatsObject: HeartbeatsInIndexedDB): Promise {\n const canUseIndexedDB = await this._canUseIndexedDBPromise;\n if (!canUseIndexedDB) {\n return;\n } else {\n const existingHeartbeatsObject = await this.read();\n return writeHeartbeatsToIndexedDB(this.app, {\n lastSentHeartbeatDate:\n heartbeatsObject.lastSentHeartbeatDate ??\n existingHeartbeatsObject.lastSentHeartbeatDate,\n heartbeats: [\n ...existingHeartbeatsObject.heartbeats,\n ...heartbeatsObject.heartbeats\n ]\n });\n }\n }\n}\n\n/**\n * Calculate bytes of a HeartbeatsByUserAgent array after being wrapped\n * in a platform logging header JSON object, stringified, and converted\n * to base 64.\n */\nexport function countBytes(heartbeatsCache: HeartbeatsByUserAgent[]): number {\n // base64 has a restricted set of characters, all of which should be 1 byte.\n return base64urlEncodeWithoutPadding(\n // heartbeatsCache wrapper properties\n JSON.stringify({ version: 2, heartbeats: heartbeatsCache })\n ).length;\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Component, ComponentType } from '@firebase/component';\nimport { PlatformLoggerServiceImpl } from './platformLoggerService';\nimport { name, version } from '../package.json';\nimport { _registerComponent } from './internal';\nimport { registerVersion } from './api';\nimport { HeartbeatServiceImpl } from './heartbeatService';\n\nexport function registerCoreComponents(variant?: string): void {\n _registerComponent(\n new Component(\n 'platform-logger',\n container => new PlatformLoggerServiceImpl(container),\n ComponentType.PRIVATE\n )\n );\n _registerComponent(\n new Component(\n 'heartbeat',\n container => new HeartbeatServiceImpl(container),\n ComponentType.PRIVATE\n )\n );\n\n // Register `app` package.\n registerVersion(name, version, variant);\n // BUILD_TARGET will be replaced by values like esm5, esm2017, cjs5, etc during the compilation\n registerVersion(name, version, '__BUILD_TARGET__');\n // Register platform SDK identifier (no version).\n registerVersion('fire-js', '');\n}\n", "/**\n * Firebase App\n *\n * @remarks This package coordinates the communication between the different Firebase components\n * @packageDocumentation\n */\n\n/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { registerCoreComponents } from './registerCoreComponents';\n\nexport * from './api';\nexport * from './internal';\nexport * from './public-types';\n\nregisterCoreComponents('__RUNTIME_ENV__');\n", "/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { registerVersion } from '@firebase/app';\nimport { name, version } from '../package.json';\n\nregisterVersion(name, version, 'app');\nexport * from '@firebase/app';\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { version } from '../../package.json';\n\nexport const PENDING_TIMEOUT_MS = 10000;\n\nexport const PACKAGE_VERSION = `w:${version}`;\nexport const INTERNAL_AUTH_VERSION = 'FIS_v2';\n\nexport const INSTALLATIONS_API_URL =\n 'https://firebaseinstallations.googleapis.com/v1';\n\nexport const TOKEN_EXPIRATION_BUFFER = 60 * 60 * 1000; // One hour\n\nexport const SERVICE = 'installations';\nexport const SERVICE_NAME = 'Installations';\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ErrorFactory, FirebaseError } from '@firebase/util';\nimport { SERVICE, SERVICE_NAME } from './constants';\n\nexport const enum ErrorCode {\n MISSING_APP_CONFIG_VALUES = 'missing-app-config-values',\n NOT_REGISTERED = 'not-registered',\n INSTALLATION_NOT_FOUND = 'installation-not-found',\n REQUEST_FAILED = 'request-failed',\n APP_OFFLINE = 'app-offline',\n DELETE_PENDING_REGISTRATION = 'delete-pending-registration'\n}\n\nconst ERROR_DESCRIPTION_MAP: { readonly [key in ErrorCode]: string } = {\n [ErrorCode.MISSING_APP_CONFIG_VALUES]:\n 'Missing App configuration value: \"{$valueName}\"',\n [ErrorCode.NOT_REGISTERED]: 'Firebase Installation is not registered.',\n [ErrorCode.INSTALLATION_NOT_FOUND]: 'Firebase Installation not found.',\n [ErrorCode.REQUEST_FAILED]:\n '{$requestName} request failed with error \"{$serverCode} {$serverStatus}: {$serverMessage}\"',\n [ErrorCode.APP_OFFLINE]: 'Could not process request. Application offline.',\n [ErrorCode.DELETE_PENDING_REGISTRATION]:\n \"Can't delete installation while there is a pending registration request.\"\n};\n\ninterface ErrorParams {\n [ErrorCode.MISSING_APP_CONFIG_VALUES]: {\n valueName: string;\n };\n [ErrorCode.REQUEST_FAILED]: {\n requestName: string;\n [index: string]: string | number; // to make Typescript 3.8 happy\n } & ServerErrorData;\n}\n\nexport const ERROR_FACTORY = new ErrorFactory(\n SERVICE,\n SERVICE_NAME,\n ERROR_DESCRIPTION_MAP\n);\n\nexport interface ServerErrorData {\n serverCode: number;\n serverMessage: string;\n serverStatus: string;\n}\n\nexport type ServerError = FirebaseError & { customData: ServerErrorData };\n\n/** Returns true if error is a FirebaseError that is based on an error from the server. */\nexport function isServerError(error: unknown): error is ServerError {\n return (\n error instanceof FirebaseError &&\n error.code.includes(ErrorCode.REQUEST_FAILED)\n );\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { FirebaseError } from '@firebase/util';\nimport { GenerateAuthTokenResponse } from '../interfaces/api-response';\nimport {\n CompletedAuthToken,\n RegisteredInstallationEntry,\n RequestStatus\n} from '../interfaces/installation-entry';\nimport {\n INSTALLATIONS_API_URL,\n INTERNAL_AUTH_VERSION\n} from '../util/constants';\nimport { ERROR_FACTORY, ErrorCode } from '../util/errors';\nimport { AppConfig } from '../interfaces/installation-impl';\n\nexport function getInstallationsEndpoint({ projectId }: AppConfig): string {\n return `${INSTALLATIONS_API_URL}/projects/${projectId}/installations`;\n}\n\nexport function extractAuthTokenInfoFromResponse(\n response: GenerateAuthTokenResponse\n): CompletedAuthToken {\n return {\n token: response.token,\n requestStatus: RequestStatus.COMPLETED,\n expiresIn: getExpiresInFromResponseExpiresIn(response.expiresIn),\n creationTime: Date.now()\n };\n}\n\nexport async function getErrorFromResponse(\n requestName: string,\n response: Response\n): Promise {\n const responseJson: ErrorResponse = await response.json();\n const errorData = responseJson.error;\n return ERROR_FACTORY.create(ErrorCode.REQUEST_FAILED, {\n requestName,\n serverCode: errorData.code,\n serverMessage: errorData.message,\n serverStatus: errorData.status\n });\n}\n\nexport function getHeaders({ apiKey }: AppConfig): Headers {\n return new Headers({\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n 'x-goog-api-key': apiKey\n });\n}\n\nexport function getHeadersWithAuth(\n appConfig: AppConfig,\n { refreshToken }: RegisteredInstallationEntry\n): Headers {\n const headers = getHeaders(appConfig);\n headers.append('Authorization', getAuthorizationHeader(refreshToken));\n return headers;\n}\n\nexport interface ErrorResponse {\n error: {\n code: number;\n message: string;\n status: string;\n };\n}\n\n/**\n * Calls the passed in fetch wrapper and returns the response.\n * If the returned response has a status of 5xx, re-runs the function once and\n * returns the response.\n */\nexport async function retryIfServerError(\n fn: () => Promise\n): Promise {\n const result = await fn();\n\n if (result.status >= 500 && result.status < 600) {\n // Internal Server Error. Retry request.\n return fn();\n }\n\n return result;\n}\n\nfunction getExpiresInFromResponseExpiresIn(responseExpiresIn: string): number {\n // This works because the server will never respond with fractions of a second.\n return Number(responseExpiresIn.replace('s', '000'));\n}\n\nfunction getAuthorizationHeader(refreshToken: string): string {\n return `${INTERNAL_AUTH_VERSION} ${refreshToken}`;\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { CreateInstallationResponse } from '../interfaces/api-response';\nimport {\n InProgressInstallationEntry,\n RegisteredInstallationEntry,\n RequestStatus\n} from '../interfaces/installation-entry';\nimport { INTERNAL_AUTH_VERSION, PACKAGE_VERSION } from '../util/constants';\nimport {\n extractAuthTokenInfoFromResponse,\n getErrorFromResponse,\n getHeaders,\n getInstallationsEndpoint,\n retryIfServerError\n} from './common';\nimport { FirebaseInstallationsImpl } from '../interfaces/installation-impl';\n\nexport async function createInstallationRequest(\n { appConfig, heartbeatServiceProvider }: FirebaseInstallationsImpl,\n { fid }: InProgressInstallationEntry\n): Promise {\n const endpoint = getInstallationsEndpoint(appConfig);\n\n const headers = getHeaders(appConfig);\n\n // If heartbeat service exists, add the heartbeat string to the header.\n const heartbeatService = heartbeatServiceProvider.getImmediate({\n optional: true\n });\n if (heartbeatService) {\n const heartbeatsHeader = await heartbeatService.getHeartbeatsHeader();\n if (heartbeatsHeader) {\n headers.append('x-firebase-client', heartbeatsHeader);\n }\n }\n\n const body = {\n fid,\n authVersion: INTERNAL_AUTH_VERSION,\n appId: appConfig.appId,\n sdkVersion: PACKAGE_VERSION\n };\n\n const request: RequestInit = {\n method: 'POST',\n headers,\n body: JSON.stringify(body)\n };\n\n const response = await retryIfServerError(() => fetch(endpoint, request));\n if (response.ok) {\n const responseValue: CreateInstallationResponse = await response.json();\n const registeredInstallationEntry: RegisteredInstallationEntry = {\n fid: responseValue.fid || fid,\n registrationStatus: RequestStatus.COMPLETED,\n refreshToken: responseValue.refreshToken,\n authToken: extractAuthTokenInfoFromResponse(responseValue.authToken)\n };\n return registeredInstallationEntry;\n } else {\n throw await getErrorFromResponse('Create Installation', response);\n }\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/** Returns a promise that resolves after given time passes. */\nexport function sleep(ms: number): Promise {\n return new Promise(resolve => {\n setTimeout(resolve, ms);\n });\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport function bufferToBase64UrlSafe(array: Uint8Array): string {\n const b64 = btoa(String.fromCharCode(...array));\n return b64.replace(/\\+/g, '-').replace(/\\//g, '_');\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { bufferToBase64UrlSafe } from './buffer-to-base64-url-safe';\n\nexport const VALID_FID_PATTERN = /^[cdef][\\w-]{21}$/;\nexport const INVALID_FID = '';\n\n/**\n * Generates a new FID using random values from Web Crypto API.\n * Returns an empty string if FID generation fails for any reason.\n */\nexport function generateFid(): string {\n try {\n // A valid FID has exactly 22 base64 characters, which is 132 bits, or 16.5\n // bytes. our implementation generates a 17 byte array instead.\n const fidByteArray = new Uint8Array(17);\n const crypto =\n self.crypto || (self as unknown as { msCrypto: Crypto }).msCrypto;\n crypto.getRandomValues(fidByteArray);\n\n // Replace the first 4 random bits with the constant FID header of 0b0111.\n fidByteArray[0] = 0b01110000 + (fidByteArray[0] % 0b00010000);\n\n const fid = encode(fidByteArray);\n\n return VALID_FID_PATTERN.test(fid) ? fid : INVALID_FID;\n } catch {\n // FID generation errored\n return INVALID_FID;\n }\n}\n\n/** Converts a FID Uint8Array to a base64 string representation. */\nfunction encode(fidByteArray: Uint8Array): string {\n const b64String = bufferToBase64UrlSafe(fidByteArray);\n\n // Remove the 23rd character that was added because of the extra 4 bits at the\n // end of our 17 byte array, and the '=' padding.\n return b64String.substr(0, 22);\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { AppConfig } from '../interfaces/installation-impl';\n\n/** Returns a string key that can be used to identify the app. */\nexport function getKey(appConfig: AppConfig): string {\n return `${appConfig.appName}!${appConfig.appId}`;\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { getKey } from '../util/get-key';\nimport { AppConfig } from '../interfaces/installation-impl';\nimport { IdChangeCallbackFn } from '../api';\n\nconst fidChangeCallbacks: Map> = new Map();\n\n/**\n * Calls the onIdChange callbacks with the new FID value, and broadcasts the\n * change to other tabs.\n */\nexport function fidChanged(appConfig: AppConfig, fid: string): void {\n const key = getKey(appConfig);\n\n callFidChangeCallbacks(key, fid);\n broadcastFidChange(key, fid);\n}\n\nexport function addCallback(\n appConfig: AppConfig,\n callback: IdChangeCallbackFn\n): void {\n // Open the broadcast channel if it's not already open,\n // to be able to listen to change events from other tabs.\n getBroadcastChannel();\n\n const key = getKey(appConfig);\n\n let callbackSet = fidChangeCallbacks.get(key);\n if (!callbackSet) {\n callbackSet = new Set();\n fidChangeCallbacks.set(key, callbackSet);\n }\n callbackSet.add(callback);\n}\n\nexport function removeCallback(\n appConfig: AppConfig,\n callback: IdChangeCallbackFn\n): void {\n const key = getKey(appConfig);\n\n const callbackSet = fidChangeCallbacks.get(key);\n\n if (!callbackSet) {\n return;\n }\n\n callbackSet.delete(callback);\n if (callbackSet.size === 0) {\n fidChangeCallbacks.delete(key);\n }\n\n // Close broadcast channel if there are no more callbacks.\n closeBroadcastChannel();\n}\n\nfunction callFidChangeCallbacks(key: string, fid: string): void {\n const callbacks = fidChangeCallbacks.get(key);\n if (!callbacks) {\n return;\n }\n\n for (const callback of callbacks) {\n callback(fid);\n }\n}\n\nfunction broadcastFidChange(key: string, fid: string): void {\n const channel = getBroadcastChannel();\n if (channel) {\n channel.postMessage({ key, fid });\n }\n closeBroadcastChannel();\n}\n\nlet broadcastChannel: BroadcastChannel | null = null;\n/** Opens and returns a BroadcastChannel if it is supported by the browser. */\nfunction getBroadcastChannel(): BroadcastChannel | null {\n if (!broadcastChannel && 'BroadcastChannel' in self) {\n broadcastChannel = new BroadcastChannel('[Firebase] FID Change');\n broadcastChannel.onmessage = e => {\n callFidChangeCallbacks(e.data.key, e.data.fid);\n };\n }\n return broadcastChannel;\n}\n\nfunction closeBroadcastChannel(): void {\n if (fidChangeCallbacks.size === 0 && broadcastChannel) {\n broadcastChannel.close();\n broadcastChannel = null;\n }\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { DBSchema, IDBPDatabase, openDB } from 'idb';\nimport { AppConfig } from '../interfaces/installation-impl';\nimport { InstallationEntry } from '../interfaces/installation-entry';\nimport { getKey } from '../util/get-key';\nimport { fidChanged } from './fid-changed';\n\nconst DATABASE_NAME = 'firebase-installations-database';\nconst DATABASE_VERSION = 1;\nconst OBJECT_STORE_NAME = 'firebase-installations-store';\n\ninterface InstallationsDB extends DBSchema {\n 'firebase-installations-store': {\n key: string;\n value: InstallationEntry | undefined;\n };\n}\n\nlet dbPromise: Promise> | null = null;\nfunction getDbPromise(): Promise> {\n if (!dbPromise) {\n dbPromise = openDB(DATABASE_NAME, DATABASE_VERSION, {\n upgrade: (db, oldVersion) => {\n // We don't use 'break' in this switch statement, the fall-through\n // behavior is what we want, because if there are multiple versions between\n // the old version and the current version, we want ALL the migrations\n // that correspond to those versions to run, not only the last one.\n // eslint-disable-next-line default-case\n switch (oldVersion) {\n case 0:\n db.createObjectStore(OBJECT_STORE_NAME);\n }\n }\n });\n }\n return dbPromise;\n}\n\n/** Gets record(s) from the objectStore that match the given key. */\nexport async function get(\n appConfig: AppConfig\n): Promise {\n const key = getKey(appConfig);\n const db = await getDbPromise();\n return db\n .transaction(OBJECT_STORE_NAME)\n .objectStore(OBJECT_STORE_NAME)\n .get(key) as Promise;\n}\n\n/** Assigns or overwrites the record for the given key with the given value. */\nexport async function set(\n appConfig: AppConfig,\n value: ValueType\n): Promise {\n const key = getKey(appConfig);\n const db = await getDbPromise();\n const tx = db.transaction(OBJECT_STORE_NAME, 'readwrite');\n const objectStore = tx.objectStore(OBJECT_STORE_NAME);\n const oldValue = (await objectStore.get(key)) as InstallationEntry;\n await objectStore.put(value, key);\n await tx.done;\n\n if (!oldValue || oldValue.fid !== value.fid) {\n fidChanged(appConfig, value.fid);\n }\n\n return value;\n}\n\n/** Removes record(s) from the objectStore that match the given key. */\nexport async function remove(appConfig: AppConfig): Promise {\n const key = getKey(appConfig);\n const db = await getDbPromise();\n const tx = db.transaction(OBJECT_STORE_NAME, 'readwrite');\n await tx.objectStore(OBJECT_STORE_NAME).delete(key);\n await tx.done;\n}\n\n/**\n * Atomically updates a record with the result of updateFn, which gets\n * called with the current value. If newValue is undefined, the record is\n * deleted instead.\n * @return Updated value\n */\nexport async function update(\n appConfig: AppConfig,\n updateFn: (previousValue: InstallationEntry | undefined) => ValueType\n): Promise {\n const key = getKey(appConfig);\n const db = await getDbPromise();\n const tx = db.transaction(OBJECT_STORE_NAME, 'readwrite');\n const store = tx.objectStore(OBJECT_STORE_NAME);\n const oldValue: InstallationEntry | undefined = (await store.get(\n key\n )) as InstallationEntry;\n const newValue = updateFn(oldValue);\n\n if (newValue === undefined) {\n await store.delete(key);\n } else {\n await store.put(newValue, key);\n }\n await tx.done;\n\n if (newValue && (!oldValue || oldValue.fid !== newValue.fid)) {\n fidChanged(appConfig, newValue.fid);\n }\n\n return newValue;\n}\n\nexport async function clear(): Promise {\n const db = await getDbPromise();\n const tx = db.transaction(OBJECT_STORE_NAME, 'readwrite');\n await tx.objectStore(OBJECT_STORE_NAME).clear();\n await tx.done;\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { createInstallationRequest } from '../functions/create-installation-request';\nimport {\n AppConfig,\n FirebaseInstallationsImpl\n} from '../interfaces/installation-impl';\nimport {\n InProgressInstallationEntry,\n InstallationEntry,\n RegisteredInstallationEntry,\n RequestStatus\n} from '../interfaces/installation-entry';\nimport { PENDING_TIMEOUT_MS } from '../util/constants';\nimport { ERROR_FACTORY, ErrorCode, isServerError } from '../util/errors';\nimport { sleep } from '../util/sleep';\nimport { generateFid, INVALID_FID } from './generate-fid';\nimport { remove, set, update } from './idb-manager';\n\nexport interface InstallationEntryWithRegistrationPromise {\n installationEntry: InstallationEntry;\n /** Exist iff the installationEntry is not registered. */\n registrationPromise?: Promise;\n}\n\n/**\n * Updates and returns the InstallationEntry from the database.\n * Also triggers a registration request if it is necessary and possible.\n */\nexport async function getInstallationEntry(\n installations: FirebaseInstallationsImpl\n): Promise {\n let registrationPromise: Promise | undefined;\n\n const installationEntry = await update(installations.appConfig, oldEntry => {\n const installationEntry = updateOrCreateInstallationEntry(oldEntry);\n const entryWithPromise = triggerRegistrationIfNecessary(\n installations,\n installationEntry\n );\n registrationPromise = entryWithPromise.registrationPromise;\n return entryWithPromise.installationEntry;\n });\n\n if (installationEntry.fid === INVALID_FID) {\n // FID generation failed. Waiting for the FID from the server.\n return { installationEntry: await registrationPromise! };\n }\n\n return {\n installationEntry,\n registrationPromise\n };\n}\n\n/**\n * Creates a new Installation Entry if one does not exist.\n * Also clears timed out pending requests.\n */\nfunction updateOrCreateInstallationEntry(\n oldEntry: InstallationEntry | undefined\n): InstallationEntry {\n const entry: InstallationEntry = oldEntry || {\n fid: generateFid(),\n registrationStatus: RequestStatus.NOT_STARTED\n };\n\n return clearTimedOutRequest(entry);\n}\n\n/**\n * If the Firebase Installation is not registered yet, this will trigger the\n * registration and return an InProgressInstallationEntry.\n *\n * If registrationPromise does not exist, the installationEntry is guaranteed\n * to be registered.\n */\nfunction triggerRegistrationIfNecessary(\n installations: FirebaseInstallationsImpl,\n installationEntry: InstallationEntry\n): InstallationEntryWithRegistrationPromise {\n if (installationEntry.registrationStatus === RequestStatus.NOT_STARTED) {\n if (!navigator.onLine) {\n // Registration required but app is offline.\n const registrationPromiseWithError = Promise.reject(\n ERROR_FACTORY.create(ErrorCode.APP_OFFLINE)\n );\n return {\n installationEntry,\n registrationPromise: registrationPromiseWithError\n };\n }\n\n // Try registering. Change status to IN_PROGRESS.\n const inProgressEntry: InProgressInstallationEntry = {\n fid: installationEntry.fid,\n registrationStatus: RequestStatus.IN_PROGRESS,\n registrationTime: Date.now()\n };\n const registrationPromise = registerInstallation(\n installations,\n inProgressEntry\n );\n return { installationEntry: inProgressEntry, registrationPromise };\n } else if (\n installationEntry.registrationStatus === RequestStatus.IN_PROGRESS\n ) {\n return {\n installationEntry,\n registrationPromise: waitUntilFidRegistration(installations)\n };\n } else {\n return { installationEntry };\n }\n}\n\n/** This will be executed only once for each new Firebase Installation. */\nasync function registerInstallation(\n installations: FirebaseInstallationsImpl,\n installationEntry: InProgressInstallationEntry\n): Promise {\n try {\n const registeredInstallationEntry = await createInstallationRequest(\n installations,\n installationEntry\n );\n return set(installations.appConfig, registeredInstallationEntry);\n } catch (e) {\n if (isServerError(e) && e.customData.serverCode === 409) {\n // Server returned a \"FID can not be used\" error.\n // Generate a new ID next time.\n await remove(installations.appConfig);\n } else {\n // Registration failed. Set FID as not registered.\n await set(installations.appConfig, {\n fid: installationEntry.fid,\n registrationStatus: RequestStatus.NOT_STARTED\n });\n }\n throw e;\n }\n}\n\n/** Call if FID registration is pending in another request. */\nasync function waitUntilFidRegistration(\n installations: FirebaseInstallationsImpl\n): Promise {\n // Unfortunately, there is no way of reliably observing when a value in\n // IndexedDB changes (yet, see https://github.com/WICG/indexed-db-observers),\n // so we need to poll.\n\n let entry: InstallationEntry = await updateInstallationRequest(\n installations.appConfig\n );\n while (entry.registrationStatus === RequestStatus.IN_PROGRESS) {\n // createInstallation request still in progress.\n await sleep(100);\n\n entry = await updateInstallationRequest(installations.appConfig);\n }\n\n if (entry.registrationStatus === RequestStatus.NOT_STARTED) {\n // The request timed out or failed in a different call. Try again.\n const { installationEntry, registrationPromise } =\n await getInstallationEntry(installations);\n\n if (registrationPromise) {\n return registrationPromise;\n } else {\n // if there is no registrationPromise, entry is registered.\n return installationEntry as RegisteredInstallationEntry;\n }\n }\n\n return entry;\n}\n\n/**\n * Called only if there is a CreateInstallation request in progress.\n *\n * Updates the InstallationEntry in the DB based on the status of the\n * CreateInstallation request.\n *\n * Returns the updated InstallationEntry.\n */\nfunction updateInstallationRequest(\n appConfig: AppConfig\n): Promise {\n return update(appConfig, oldEntry => {\n if (!oldEntry) {\n throw ERROR_FACTORY.create(ErrorCode.INSTALLATION_NOT_FOUND);\n }\n return clearTimedOutRequest(oldEntry);\n });\n}\n\nfunction clearTimedOutRequest(entry: InstallationEntry): InstallationEntry {\n if (hasInstallationRequestTimedOut(entry)) {\n return {\n fid: entry.fid,\n registrationStatus: RequestStatus.NOT_STARTED\n };\n }\n\n return entry;\n}\n\nfunction hasInstallationRequestTimedOut(\n installationEntry: InstallationEntry\n): boolean {\n return (\n installationEntry.registrationStatus === RequestStatus.IN_PROGRESS &&\n installationEntry.registrationTime + PENDING_TIMEOUT_MS < Date.now()\n );\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { GenerateAuthTokenResponse } from '../interfaces/api-response';\nimport {\n CompletedAuthToken,\n RegisteredInstallationEntry\n} from '../interfaces/installation-entry';\nimport { PACKAGE_VERSION } from '../util/constants';\nimport {\n extractAuthTokenInfoFromResponse,\n getErrorFromResponse,\n getHeadersWithAuth,\n getInstallationsEndpoint,\n retryIfServerError\n} from './common';\nimport {\n FirebaseInstallationsImpl,\n AppConfig\n} from '../interfaces/installation-impl';\n\nexport async function generateAuthTokenRequest(\n { appConfig, heartbeatServiceProvider }: FirebaseInstallationsImpl,\n installationEntry: RegisteredInstallationEntry\n): Promise {\n const endpoint = getGenerateAuthTokenEndpoint(appConfig, installationEntry);\n\n const headers = getHeadersWithAuth(appConfig, installationEntry);\n\n // If heartbeat service exists, add the heartbeat string to the header.\n const heartbeatService = heartbeatServiceProvider.getImmediate({\n optional: true\n });\n if (heartbeatService) {\n const heartbeatsHeader = await heartbeatService.getHeartbeatsHeader();\n if (heartbeatsHeader) {\n headers.append('x-firebase-client', heartbeatsHeader);\n }\n }\n\n const body = {\n installation: {\n sdkVersion: PACKAGE_VERSION,\n appId: appConfig.appId\n }\n };\n\n const request: RequestInit = {\n method: 'POST',\n headers,\n body: JSON.stringify(body)\n };\n\n const response = await retryIfServerError(() => fetch(endpoint, request));\n if (response.ok) {\n const responseValue: GenerateAuthTokenResponse = await response.json();\n const completedAuthToken: CompletedAuthToken =\n extractAuthTokenInfoFromResponse(responseValue);\n return completedAuthToken;\n } else {\n throw await getErrorFromResponse('Generate Auth Token', response);\n }\n}\n\nfunction getGenerateAuthTokenEndpoint(\n appConfig: AppConfig,\n { fid }: RegisteredInstallationEntry\n): string {\n return `${getInstallationsEndpoint(appConfig)}/${fid}/authTokens:generate`;\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { generateAuthTokenRequest } from '../functions/generate-auth-token-request';\nimport {\n AppConfig,\n FirebaseInstallationsImpl\n} from '../interfaces/installation-impl';\nimport {\n AuthToken,\n CompletedAuthToken,\n InProgressAuthToken,\n InstallationEntry,\n RegisteredInstallationEntry,\n RequestStatus\n} from '../interfaces/installation-entry';\nimport { PENDING_TIMEOUT_MS, TOKEN_EXPIRATION_BUFFER } from '../util/constants';\nimport { ERROR_FACTORY, ErrorCode, isServerError } from '../util/errors';\nimport { sleep } from '../util/sleep';\nimport { remove, set, update } from './idb-manager';\n\n/**\n * Returns a valid authentication token for the installation. Generates a new\n * token if one doesn't exist, is expired or about to expire.\n *\n * Should only be called if the Firebase Installation is registered.\n */\nexport async function refreshAuthToken(\n installations: FirebaseInstallationsImpl,\n forceRefresh = false\n): Promise {\n let tokenPromise: Promise | undefined;\n const entry = await update(installations.appConfig, oldEntry => {\n if (!isEntryRegistered(oldEntry)) {\n throw ERROR_FACTORY.create(ErrorCode.NOT_REGISTERED);\n }\n\n const oldAuthToken = oldEntry.authToken;\n if (!forceRefresh && isAuthTokenValid(oldAuthToken)) {\n // There is a valid token in the DB.\n return oldEntry;\n } else if (oldAuthToken.requestStatus === RequestStatus.IN_PROGRESS) {\n // There already is a token request in progress.\n tokenPromise = waitUntilAuthTokenRequest(installations, forceRefresh);\n return oldEntry;\n } else {\n // No token or token expired.\n if (!navigator.onLine) {\n throw ERROR_FACTORY.create(ErrorCode.APP_OFFLINE);\n }\n\n const inProgressEntry = makeAuthTokenRequestInProgressEntry(oldEntry);\n tokenPromise = fetchAuthTokenFromServer(installations, inProgressEntry);\n return inProgressEntry;\n }\n });\n\n const authToken = tokenPromise\n ? await tokenPromise\n : (entry.authToken as CompletedAuthToken);\n return authToken;\n}\n\n/**\n * Call only if FID is registered and Auth Token request is in progress.\n *\n * Waits until the current pending request finishes. If the request times out,\n * tries once in this thread as well.\n */\nasync function waitUntilAuthTokenRequest(\n installations: FirebaseInstallationsImpl,\n forceRefresh: boolean\n): Promise {\n // Unfortunately, there is no way of reliably observing when a value in\n // IndexedDB changes (yet, see https://github.com/WICG/indexed-db-observers),\n // so we need to poll.\n\n let entry = await updateAuthTokenRequest(installations.appConfig);\n while (entry.authToken.requestStatus === RequestStatus.IN_PROGRESS) {\n // generateAuthToken still in progress.\n await sleep(100);\n\n entry = await updateAuthTokenRequest(installations.appConfig);\n }\n\n const authToken = entry.authToken;\n if (authToken.requestStatus === RequestStatus.NOT_STARTED) {\n // The request timed out or failed in a different call. Try again.\n return refreshAuthToken(installations, forceRefresh);\n } else {\n return authToken;\n }\n}\n\n/**\n * Called only if there is a GenerateAuthToken request in progress.\n *\n * Updates the InstallationEntry in the DB based on the status of the\n * GenerateAuthToken request.\n *\n * Returns the updated InstallationEntry.\n */\nfunction updateAuthTokenRequest(\n appConfig: AppConfig\n): Promise {\n return update(appConfig, oldEntry => {\n if (!isEntryRegistered(oldEntry)) {\n throw ERROR_FACTORY.create(ErrorCode.NOT_REGISTERED);\n }\n\n const oldAuthToken = oldEntry.authToken;\n if (hasAuthTokenRequestTimedOut(oldAuthToken)) {\n return {\n ...oldEntry,\n authToken: { requestStatus: RequestStatus.NOT_STARTED }\n };\n }\n\n return oldEntry;\n });\n}\n\nasync function fetchAuthTokenFromServer(\n installations: FirebaseInstallationsImpl,\n installationEntry: RegisteredInstallationEntry\n): Promise {\n try {\n const authToken = await generateAuthTokenRequest(\n installations,\n installationEntry\n );\n const updatedInstallationEntry: RegisteredInstallationEntry = {\n ...installationEntry,\n authToken\n };\n await set(installations.appConfig, updatedInstallationEntry);\n return authToken;\n } catch (e) {\n if (\n isServerError(e) &&\n (e.customData.serverCode === 401 || e.customData.serverCode === 404)\n ) {\n // Server returned a \"FID not found\" or a \"Invalid authentication\" error.\n // Generate a new ID next time.\n await remove(installations.appConfig);\n } else {\n const updatedInstallationEntry: RegisteredInstallationEntry = {\n ...installationEntry,\n authToken: { requestStatus: RequestStatus.NOT_STARTED }\n };\n await set(installations.appConfig, updatedInstallationEntry);\n }\n throw e;\n }\n}\n\nfunction isEntryRegistered(\n installationEntry: InstallationEntry | undefined\n): installationEntry is RegisteredInstallationEntry {\n return (\n installationEntry !== undefined &&\n installationEntry.registrationStatus === RequestStatus.COMPLETED\n );\n}\n\nfunction isAuthTokenValid(authToken: AuthToken): boolean {\n return (\n authToken.requestStatus === RequestStatus.COMPLETED &&\n !isAuthTokenExpired(authToken)\n );\n}\n\nfunction isAuthTokenExpired(authToken: CompletedAuthToken): boolean {\n const now = Date.now();\n return (\n now < authToken.creationTime ||\n authToken.creationTime + authToken.expiresIn < now + TOKEN_EXPIRATION_BUFFER\n );\n}\n\n/** Returns an updated InstallationEntry with an InProgressAuthToken. */\nfunction makeAuthTokenRequestInProgressEntry(\n oldEntry: RegisteredInstallationEntry\n): RegisteredInstallationEntry {\n const inProgressAuthToken: InProgressAuthToken = {\n requestStatus: RequestStatus.IN_PROGRESS,\n requestTime: Date.now()\n };\n return {\n ...oldEntry,\n authToken: inProgressAuthToken\n };\n}\n\nfunction hasAuthTokenRequestTimedOut(authToken: AuthToken): boolean {\n return (\n authToken.requestStatus === RequestStatus.IN_PROGRESS &&\n authToken.requestTime + PENDING_TIMEOUT_MS < Date.now()\n );\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { getInstallationEntry } from '../helpers/get-installation-entry';\nimport { refreshAuthToken } from '../helpers/refresh-auth-token';\nimport { FirebaseInstallationsImpl } from '../interfaces/installation-impl';\nimport { Installations } from '../interfaces/public-types';\n\n/**\n * Creates a Firebase Installation if there isn't one for the app and\n * returns the Installation ID.\n * @param installations - The `Installations` instance.\n *\n * @public\n */\nexport async function getId(installations: Installations): Promise {\n const installationsImpl = installations as FirebaseInstallationsImpl;\n const { installationEntry, registrationPromise } = await getInstallationEntry(\n installationsImpl\n );\n\n if (registrationPromise) {\n registrationPromise.catch(console.error);\n } else {\n // If the installation is already registered, update the authentication\n // token if needed.\n refreshAuthToken(installationsImpl).catch(console.error);\n }\n\n return installationEntry.fid;\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { getInstallationEntry } from '../helpers/get-installation-entry';\nimport { refreshAuthToken } from '../helpers/refresh-auth-token';\nimport { FirebaseInstallationsImpl } from '../interfaces/installation-impl';\nimport { Installations } from '../interfaces/public-types';\n\n/**\n * Returns a Firebase Installations auth token, identifying the current\n * Firebase Installation.\n * @param installations - The `Installations` instance.\n * @param forceRefresh - Force refresh regardless of token expiration.\n *\n * @public\n */\nexport async function getToken(\n installations: Installations,\n forceRefresh = false\n): Promise {\n const installationsImpl = installations as FirebaseInstallationsImpl;\n await completeInstallationRegistration(installationsImpl);\n\n // At this point we either have a Registered Installation in the DB, or we've\n // already thrown an error.\n const authToken = await refreshAuthToken(installationsImpl, forceRefresh);\n return authToken.token;\n}\n\nasync function completeInstallationRegistration(\n installations: FirebaseInstallationsImpl\n): Promise {\n const { registrationPromise } = await getInstallationEntry(installations);\n\n if (registrationPromise) {\n // A createInstallation request is in progress. Wait until it finishes.\n await registrationPromise;\n }\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { AppConfig } from '../interfaces/installation-impl';\nimport { RegisteredInstallationEntry } from '../interfaces/installation-entry';\nimport {\n getErrorFromResponse,\n getHeadersWithAuth,\n getInstallationsEndpoint,\n retryIfServerError\n} from './common';\n\nexport async function deleteInstallationRequest(\n appConfig: AppConfig,\n installationEntry: RegisteredInstallationEntry\n): Promise {\n const endpoint = getDeleteEndpoint(appConfig, installationEntry);\n\n const headers = getHeadersWithAuth(appConfig, installationEntry);\n const request: RequestInit = {\n method: 'DELETE',\n headers\n };\n\n const response = await retryIfServerError(() => fetch(endpoint, request));\n if (!response.ok) {\n throw await getErrorFromResponse('Delete Installation', response);\n }\n}\n\nfunction getDeleteEndpoint(\n appConfig: AppConfig,\n { fid }: RegisteredInstallationEntry\n): string {\n return `${getInstallationsEndpoint(appConfig)}/${fid}`;\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { deleteInstallationRequest } from '../functions/delete-installation-request';\nimport { remove, update } from '../helpers/idb-manager';\nimport { RequestStatus } from '../interfaces/installation-entry';\nimport { ERROR_FACTORY, ErrorCode } from '../util/errors';\nimport { FirebaseInstallationsImpl } from '../interfaces/installation-impl';\nimport { Installations } from '../interfaces/public-types';\n\n/**\n * Deletes the Firebase Installation and all associated data.\n * @param installations - The `Installations` instance.\n *\n * @public\n */\nexport async function deleteInstallations(\n installations: Installations\n): Promise {\n const { appConfig } = installations as FirebaseInstallationsImpl;\n\n const entry = await update(appConfig, oldEntry => {\n if (oldEntry && oldEntry.registrationStatus === RequestStatus.NOT_STARTED) {\n // Delete the unregistered entry without sending a deleteInstallation request.\n return undefined;\n }\n return oldEntry;\n });\n\n if (entry) {\n if (entry.registrationStatus === RequestStatus.IN_PROGRESS) {\n // Can't delete while trying to register.\n throw ERROR_FACTORY.create(ErrorCode.DELETE_PENDING_REGISTRATION);\n } else if (entry.registrationStatus === RequestStatus.COMPLETED) {\n if (!navigator.onLine) {\n throw ERROR_FACTORY.create(ErrorCode.APP_OFFLINE);\n } else {\n await deleteInstallationRequest(appConfig, entry);\n await remove(appConfig);\n }\n }\n }\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { addCallback, removeCallback } from '../helpers/fid-changed';\nimport { FirebaseInstallationsImpl } from '../interfaces/installation-impl';\nimport { Installations } from '../interfaces/public-types';\n\n/**\n * An user defined callback function that gets called when Installations ID changes.\n *\n * @public\n */\nexport type IdChangeCallbackFn = (installationId: string) => void;\n/**\n * Unsubscribe a callback function previously added via {@link IdChangeCallbackFn}.\n *\n * @public\n */\nexport type IdChangeUnsubscribeFn = () => void;\n\n/**\n * Sets a new callback that will get called when Installation ID changes.\n * Returns an unsubscribe function that will remove the callback when called.\n * @param installations - The `Installations` instance.\n * @param callback - The callback function that is invoked when FID changes.\n * @returns A function that can be called to unsubscribe.\n *\n * @public\n */\nexport function onIdChange(\n installations: Installations,\n callback: IdChangeCallbackFn\n): IdChangeUnsubscribeFn {\n const { appConfig } = installations as FirebaseInstallationsImpl;\n\n addCallback(appConfig, callback);\n return () => {\n removeCallback(appConfig, callback);\n };\n}\n", "/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { FirebaseApp, getApp, _getProvider } from '@firebase/app';\nimport { Installations } from '../interfaces/public-types';\n\n/**\n * Returns an instance of {@link Installations} associated with the given\n * {@link @firebase/app#FirebaseApp} instance.\n * @param app - The {@link @firebase/app#FirebaseApp} instance.\n *\n * @public\n */\nexport function getInstallations(app: FirebaseApp = getApp()): Installations {\n const installationsImpl = _getProvider(app, 'installations').getImmediate();\n return installationsImpl;\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { FirebaseApp, FirebaseOptions } from '@firebase/app';\nimport { FirebaseError } from '@firebase/util';\nimport { AppConfig } from '../interfaces/installation-impl';\nimport { ERROR_FACTORY, ErrorCode } from '../util/errors';\n\nexport function extractAppConfig(app: FirebaseApp): AppConfig {\n if (!app || !app.options) {\n throw getMissingValueError('App Configuration');\n }\n\n if (!app.name) {\n throw getMissingValueError('App Name');\n }\n\n // Required app config keys\n const configKeys: Array = [\n 'projectId',\n 'apiKey',\n 'appId'\n ];\n\n for (const keyName of configKeys) {\n if (!app.options[keyName]) {\n throw getMissingValueError(keyName);\n }\n }\n\n return {\n appName: app.name,\n projectId: app.options.projectId!,\n apiKey: app.options.apiKey!,\n appId: app.options.appId!\n };\n}\n\nfunction getMissingValueError(valueName: string): FirebaseError {\n return ERROR_FACTORY.create(ErrorCode.MISSING_APP_CONFIG_VALUES, {\n valueName\n });\n}\n", "/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { _registerComponent, _getProvider } from '@firebase/app';\nimport {\n Component,\n ComponentType,\n InstanceFactory,\n ComponentContainer\n} from '@firebase/component';\nimport { getId, getToken } from '../api/index';\nimport { _FirebaseInstallationsInternal } from '../interfaces/public-types';\nimport { FirebaseInstallationsImpl } from '../interfaces/installation-impl';\nimport { extractAppConfig } from '../helpers/extract-app-config';\n\nconst INSTALLATIONS_NAME = 'installations';\nconst INSTALLATIONS_NAME_INTERNAL = 'installations-internal';\n\nconst publicFactory: InstanceFactory<'installations'> = (\n container: ComponentContainer\n) => {\n const app = container.getProvider('app').getImmediate();\n // Throws if app isn't configured properly.\n const appConfig = extractAppConfig(app);\n const heartbeatServiceProvider = _getProvider(app, 'heartbeat');\n\n const installationsImpl: FirebaseInstallationsImpl = {\n app,\n appConfig,\n heartbeatServiceProvider,\n _delete: () => Promise.resolve()\n };\n return installationsImpl;\n};\n\nconst internalFactory: InstanceFactory<'installations-internal'> = (\n container: ComponentContainer\n) => {\n const app = container.getProvider('app').getImmediate();\n // Internal FIS instance relies on public FIS instance.\n const installations = _getProvider(app, INSTALLATIONS_NAME).getImmediate();\n\n const installationsInternal: _FirebaseInstallationsInternal = {\n getId: () => getId(installations),\n getToken: (forceRefresh?: boolean) => getToken(installations, forceRefresh)\n };\n return installationsInternal;\n};\n\nexport function registerInstallations(): void {\n _registerComponent(\n new Component(INSTALLATIONS_NAME, publicFactory, ComponentType.PUBLIC)\n );\n _registerComponent(\n new Component(\n INSTALLATIONS_NAME_INTERNAL,\n internalFactory,\n ComponentType.PRIVATE\n )\n );\n}\n", "/**\n * Firebase Installations\n *\n * @packageDocumentation\n */\n\n/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { registerInstallations } from './functions/config';\nimport { registerVersion } from '@firebase/app';\nimport { name, version } from '../package.json';\n\nexport * from './api';\nexport * from './interfaces/public-types';\n\nregisterInstallations();\nregisterVersion(name, version);\n// BUILD_TARGET will be replaced by values like esm5, esm2017, cjs5, etc during the compilation\nregisterVersion(name, version, '__BUILD_TARGET__');\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport const DEFAULT_SW_PATH = '/firebase-messaging-sw.js';\nexport const DEFAULT_SW_SCOPE = '/firebase-cloud-messaging-push-scope';\n\nexport const DEFAULT_VAPID_KEY =\n 'BDOU99-h67HcA6JeFXHbSNMu7e2yNNu3RzoMj8TM4W88jITfq7ZmPvIM1Iv-4_l2LxQcYwhqby2xGpWwzjfAnG4';\n\nexport const ENDPOINT = 'https://fcmregistrations.googleapis.com/v1';\n\n/** Key of FCM Payload in Notification's data field. */\nexport const FCM_MSG = 'FCM_MSG';\n\nexport const CONSOLE_CAMPAIGN_ID = 'google.c.a.c_id';\nexport const CONSOLE_CAMPAIGN_NAME = 'google.c.a.c_l';\nexport const CONSOLE_CAMPAIGN_TIME = 'google.c.a.ts';\n/** Set to '1' if Analytics is enabled for the campaign */\nexport const CONSOLE_CAMPAIGN_ANALYTICS_ENABLED = 'google.c.a.e';\nexport const TAG = 'FirebaseMessaging: ';\nexport const MAX_NUMBER_OF_EVENTS_PER_LOG_REQUEST = 1000;\nexport const MAX_RETRIES = 3;\nexport const LOG_INTERVAL_IN_MS = 86400000; //24 hour\nexport const DEFAULT_BACKOFF_TIME_MS = 5000;\n\n// FCM log source name registered at Firelog: 'FCM_CLIENT_EVENT_LOGGING'. It uniquely identifies\n// FCM's logging configuration.\nexport const FCM_LOG_SOURCE = 1249;\n\n// Defined as in proto/messaging_event.proto. Neglecting fields that are supported.\nexport const SDK_PLATFORM_WEB = 3;\nexport const EVENT_MESSAGE_DELIVERED = 1;\n\nexport enum MessageType {\n DATA_MESSAGE = 1,\n DISPLAY_NOTIFICATION = 3\n}\n", "/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License. You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under the License\n * is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n * or implied. See the License for the specific language governing permissions and limitations under\n * the License.\n */\n\nimport {\n CONSOLE_CAMPAIGN_ANALYTICS_ENABLED,\n CONSOLE_CAMPAIGN_ID,\n CONSOLE_CAMPAIGN_NAME,\n CONSOLE_CAMPAIGN_TIME\n} from '../util/constants';\n\nexport interface MessagePayloadInternal {\n notification?: NotificationPayloadInternal;\n data?: unknown;\n fcmOptions?: FcmOptionsInternal;\n messageType?: MessageType;\n isFirebaseMessaging?: boolean;\n from: string;\n fcmMessageId: string;\n // eslint-disable-next-line camelcase\n collapse_key: string;\n}\n\nexport interface NotificationPayloadInternal extends NotificationOptions {\n title: string;\n // Supported in the Legacy Send API.\n // See:https://firebase.google.com/docs/cloud-messaging/xmpp-server-ref.\n // eslint-disable-next-line camelcase\n click_action?: string;\n}\n\n// Defined in\n// https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages#webpushfcmoptions. Note\n// that the keys are sent to the clients in snake cases which we need to convert to camel so it can\n// be exposed as a type to match the Firebase API convention.\nexport interface FcmOptionsInternal {\n link?: string;\n\n // eslint-disable-next-line camelcase\n analytics_label?: string;\n}\n\nexport enum MessageType {\n PUSH_RECEIVED = 'push-received',\n NOTIFICATION_CLICKED = 'notification-clicked'\n}\n\n/** Additional data of a message sent from the FN Console. */\nexport interface ConsoleMessageData {\n [CONSOLE_CAMPAIGN_ID]: string;\n [CONSOLE_CAMPAIGN_TIME]: string;\n [CONSOLE_CAMPAIGN_NAME]?: string;\n [CONSOLE_CAMPAIGN_ANALYTICS_ENABLED]?: '1';\n}\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport function arrayToBase64(array: Uint8Array | ArrayBuffer): string {\n const uint8Array = new Uint8Array(array);\n const base64String = btoa(String.fromCharCode(...uint8Array));\n return base64String.replace(/=/g, '').replace(/\\+/g, '-').replace(/\\//g, '_');\n}\n\nexport function base64ToArray(base64String: string): Uint8Array {\n const padding = '='.repeat((4 - (base64String.length % 4)) % 4);\n const base64 = (base64String + padding)\n .replace(/\\-/g, '+')\n .replace(/_/g, '/');\n\n const rawData = atob(base64);\n const outputArray = new Uint8Array(rawData.length);\n\n for (let i = 0; i < rawData.length; ++i) {\n outputArray[i] = rawData.charCodeAt(i);\n }\n return outputArray;\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { deleteDB, openDB } from 'idb';\n\nimport { TokenDetails } from '../interfaces/token-details';\nimport { arrayToBase64 } from './array-base64-translator';\n\n// https://github.com/firebase/firebase-js-sdk/blob/7857c212f944a2a9eb421fd4cb7370181bc034b5/packages/messaging/src/interfaces/token-details.ts\nexport interface V2TokenDetails {\n fcmToken: string;\n swScope: string;\n vapidKey: string | Uint8Array;\n subscription: PushSubscription;\n fcmSenderId: string;\n fcmPushSet: string;\n createTime?: number;\n endpoint?: string;\n auth?: string;\n p256dh?: string;\n}\n\n// https://github.com/firebase/firebase-js-sdk/blob/6b5b15ce4ea3df5df5df8a8b33a4e41e249c7715/packages/messaging/src/interfaces/token-details.ts\nexport interface V3TokenDetails {\n fcmToken: string;\n swScope: string;\n vapidKey: Uint8Array;\n fcmSenderId: string;\n fcmPushSet: string;\n endpoint: string;\n auth: ArrayBuffer;\n p256dh: ArrayBuffer;\n createTime: number;\n}\n\n// https://github.com/firebase/firebase-js-sdk/blob/9567dba664732f681fa7fe60f5b7032bb1daf4c9/packages/messaging/src/interfaces/token-details.ts\nexport interface V4TokenDetails {\n fcmToken: string;\n swScope: string;\n vapidKey: Uint8Array;\n fcmSenderId: string;\n endpoint: string;\n auth: ArrayBufferLike;\n p256dh: ArrayBufferLike;\n createTime: number;\n}\n\nconst OLD_DB_NAME = 'fcm_token_details_db';\n/**\n * The last DB version of 'fcm_token_details_db' was 4. This is one higher, so that the upgrade\n * callback is called for all versions of the old DB.\n */\nconst OLD_DB_VERSION = 5;\nconst OLD_OBJECT_STORE_NAME = 'fcm_token_object_Store';\n\nexport async function migrateOldDatabase(\n senderId: string\n): Promise {\n if ('databases' in indexedDB) {\n // indexedDb.databases() is an IndexedDB v3 API and does not exist in all browsers. TODO: Remove\n // typecast when it lands in TS types.\n const databases = await (\n indexedDB as {\n databases(): Promise>;\n }\n ).databases();\n const dbNames = databases.map(db => db.name);\n\n if (!dbNames.includes(OLD_DB_NAME)) {\n // old DB didn't exist, no need to open.\n return null;\n }\n }\n\n let tokenDetails: TokenDetails | null = null;\n\n const db = await openDB(OLD_DB_NAME, OLD_DB_VERSION, {\n upgrade: async (db, oldVersion, newVersion, upgradeTransaction) => {\n if (oldVersion < 2) {\n // Database too old, skip migration.\n return;\n }\n\n if (!db.objectStoreNames.contains(OLD_OBJECT_STORE_NAME)) {\n // Database did not exist. Nothing to do.\n return;\n }\n\n const objectStore = upgradeTransaction.objectStore(OLD_OBJECT_STORE_NAME);\n const value = await objectStore.index('fcmSenderId').get(senderId);\n await objectStore.clear();\n\n if (!value) {\n // No entry in the database, nothing to migrate.\n return;\n }\n\n if (oldVersion === 2) {\n const oldDetails = value as V2TokenDetails;\n\n if (!oldDetails.auth || !oldDetails.p256dh || !oldDetails.endpoint) {\n return;\n }\n\n tokenDetails = {\n token: oldDetails.fcmToken,\n createTime: oldDetails.createTime ?? Date.now(),\n subscriptionOptions: {\n auth: oldDetails.auth,\n p256dh: oldDetails.p256dh,\n endpoint: oldDetails.endpoint,\n swScope: oldDetails.swScope,\n vapidKey:\n typeof oldDetails.vapidKey === 'string'\n ? oldDetails.vapidKey\n : arrayToBase64(oldDetails.vapidKey)\n }\n };\n } else if (oldVersion === 3) {\n const oldDetails = value as V3TokenDetails;\n\n tokenDetails = {\n token: oldDetails.fcmToken,\n createTime: oldDetails.createTime,\n subscriptionOptions: {\n auth: arrayToBase64(oldDetails.auth),\n p256dh: arrayToBase64(oldDetails.p256dh),\n endpoint: oldDetails.endpoint,\n swScope: oldDetails.swScope,\n vapidKey: arrayToBase64(oldDetails.vapidKey)\n }\n };\n } else if (oldVersion === 4) {\n const oldDetails = value as V4TokenDetails;\n\n tokenDetails = {\n token: oldDetails.fcmToken,\n createTime: oldDetails.createTime,\n subscriptionOptions: {\n auth: arrayToBase64(oldDetails.auth),\n p256dh: arrayToBase64(oldDetails.p256dh),\n endpoint: oldDetails.endpoint,\n swScope: oldDetails.swScope,\n vapidKey: arrayToBase64(oldDetails.vapidKey)\n }\n };\n }\n }\n });\n db.close();\n\n // Delete all old databases.\n await deleteDB(OLD_DB_NAME);\n await deleteDB('fcm_vapid_details_db');\n await deleteDB('undefined');\n\n return checkTokenDetails(tokenDetails) ? tokenDetails : null;\n}\n\nfunction checkTokenDetails(\n tokenDetails: TokenDetails | null\n): tokenDetails is TokenDetails {\n if (!tokenDetails || !tokenDetails.subscriptionOptions) {\n return false;\n }\n const { subscriptionOptions } = tokenDetails;\n return (\n typeof tokenDetails.createTime === 'number' &&\n tokenDetails.createTime > 0 &&\n typeof tokenDetails.token === 'string' &&\n tokenDetails.token.length > 0 &&\n typeof subscriptionOptions.auth === 'string' &&\n subscriptionOptions.auth.length > 0 &&\n typeof subscriptionOptions.p256dh === 'string' &&\n subscriptionOptions.p256dh.length > 0 &&\n typeof subscriptionOptions.endpoint === 'string' &&\n subscriptionOptions.endpoint.length > 0 &&\n typeof subscriptionOptions.swScope === 'string' &&\n subscriptionOptions.swScope.length > 0 &&\n typeof subscriptionOptions.vapidKey === 'string' &&\n subscriptionOptions.vapidKey.length > 0\n );\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { DBSchema, IDBPDatabase, deleteDB, openDB } from 'idb';\n\nimport { FirebaseInternalDependencies } from '../interfaces/internal-dependencies';\nimport { TokenDetails } from '../interfaces/token-details';\nimport { migrateOldDatabase } from '../helpers/migrate-old-database';\n\n// Exported for tests.\nexport const DATABASE_NAME = 'firebase-messaging-database';\nconst DATABASE_VERSION = 1;\nconst OBJECT_STORE_NAME = 'firebase-messaging-store';\n\ninterface MessagingDB extends DBSchema {\n 'firebase-messaging-store': {\n key: string;\n value: TokenDetails;\n };\n}\n\nlet dbPromise: Promise> | null = null;\nfunction getDbPromise(): Promise> {\n if (!dbPromise) {\n dbPromise = openDB(DATABASE_NAME, DATABASE_VERSION, {\n upgrade: (upgradeDb, oldVersion) => {\n // We don't use 'break' in this switch statement, the fall-through behavior is what we want,\n // because if there are multiple versions between the old version and the current version, we\n // want ALL the migrations that correspond to those versions to run, not only the last one.\n // eslint-disable-next-line default-case\n switch (oldVersion) {\n case 0:\n upgradeDb.createObjectStore(OBJECT_STORE_NAME);\n }\n }\n });\n }\n return dbPromise;\n}\n\n/** Gets record(s) from the objectStore that match the given key. */\nexport async function dbGet(\n firebaseDependencies: FirebaseInternalDependencies\n): Promise {\n const key = getKey(firebaseDependencies);\n const db = await getDbPromise();\n const tokenDetails = (await db\n .transaction(OBJECT_STORE_NAME)\n .objectStore(OBJECT_STORE_NAME)\n .get(key)) as TokenDetails;\n\n if (tokenDetails) {\n return tokenDetails;\n } else {\n // Check if there is a tokenDetails object in the old DB.\n const oldTokenDetails = await migrateOldDatabase(\n firebaseDependencies.appConfig.senderId\n );\n if (oldTokenDetails) {\n await dbSet(firebaseDependencies, oldTokenDetails);\n return oldTokenDetails;\n }\n }\n}\n\n/** Assigns or overwrites the record for the given key with the given value. */\nexport async function dbSet(\n firebaseDependencies: FirebaseInternalDependencies,\n tokenDetails: TokenDetails\n): Promise {\n const key = getKey(firebaseDependencies);\n const db = await getDbPromise();\n const tx = db.transaction(OBJECT_STORE_NAME, 'readwrite');\n await tx.objectStore(OBJECT_STORE_NAME).put(tokenDetails, key);\n await tx.done;\n return tokenDetails;\n}\n\n/** Removes record(s) from the objectStore that match the given key. */\nexport async function dbRemove(\n firebaseDependencies: FirebaseInternalDependencies\n): Promise {\n const key = getKey(firebaseDependencies);\n const db = await getDbPromise();\n const tx = db.transaction(OBJECT_STORE_NAME, 'readwrite');\n await tx.objectStore(OBJECT_STORE_NAME).delete(key);\n await tx.done;\n}\n\n/** Deletes the DB. Useful for tests. */\nexport async function dbDelete(): Promise {\n if (dbPromise) {\n (await dbPromise).close();\n await deleteDB(DATABASE_NAME);\n dbPromise = null;\n }\n}\n\nfunction getKey({ appConfig }: FirebaseInternalDependencies): string {\n return appConfig.appId;\n}\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ErrorFactory, ErrorMap } from '@firebase/util';\n\nexport const enum ErrorCode {\n MISSING_APP_CONFIG_VALUES = 'missing-app-config-values',\n AVAILABLE_IN_WINDOW = 'only-available-in-window',\n AVAILABLE_IN_SW = 'only-available-in-sw',\n PERMISSION_DEFAULT = 'permission-default',\n PERMISSION_BLOCKED = 'permission-blocked',\n UNSUPPORTED_BROWSER = 'unsupported-browser',\n INDEXED_DB_UNSUPPORTED = 'indexed-db-unsupported',\n FAILED_DEFAULT_REGISTRATION = 'failed-service-worker-registration',\n TOKEN_SUBSCRIBE_FAILED = 'token-subscribe-failed',\n TOKEN_SUBSCRIBE_NO_TOKEN = 'token-subscribe-no-token',\n TOKEN_UNSUBSCRIBE_FAILED = 'token-unsubscribe-failed',\n TOKEN_UPDATE_FAILED = 'token-update-failed',\n TOKEN_UPDATE_NO_TOKEN = 'token-update-no-token',\n INVALID_BG_HANDLER = 'invalid-bg-handler',\n USE_SW_AFTER_GET_TOKEN = 'use-sw-after-get-token',\n INVALID_SW_REGISTRATION = 'invalid-sw-registration',\n USE_VAPID_KEY_AFTER_GET_TOKEN = 'use-vapid-key-after-get-token',\n INVALID_VAPID_KEY = 'invalid-vapid-key'\n}\n\nexport const ERROR_MAP: ErrorMap = {\n [ErrorCode.MISSING_APP_CONFIG_VALUES]:\n 'Missing App configuration value: \"{$valueName}\"',\n [ErrorCode.AVAILABLE_IN_WINDOW]:\n 'This method is available in a Window context.',\n [ErrorCode.AVAILABLE_IN_SW]:\n 'This method is available in a service worker context.',\n [ErrorCode.PERMISSION_DEFAULT]:\n 'The notification permission was not granted and dismissed instead.',\n [ErrorCode.PERMISSION_BLOCKED]:\n 'The notification permission was not granted and blocked instead.',\n [ErrorCode.UNSUPPORTED_BROWSER]:\n \"This browser doesn't support the API's required to use the Firebase SDK.\",\n [ErrorCode.INDEXED_DB_UNSUPPORTED]:\n \"This browser doesn't support indexedDb.open() (ex. Safari iFrame, Firefox Private Browsing, etc)\",\n [ErrorCode.FAILED_DEFAULT_REGISTRATION]:\n 'We are unable to register the default service worker. {$browserErrorMessage}',\n [ErrorCode.TOKEN_SUBSCRIBE_FAILED]:\n 'A problem occurred while subscribing the user to FCM: {$errorInfo}',\n [ErrorCode.TOKEN_SUBSCRIBE_NO_TOKEN]:\n 'FCM returned no token when subscribing the user to push.',\n [ErrorCode.TOKEN_UNSUBSCRIBE_FAILED]:\n 'A problem occurred while unsubscribing the ' +\n 'user from FCM: {$errorInfo}',\n [ErrorCode.TOKEN_UPDATE_FAILED]:\n 'A problem occurred while updating the user from FCM: {$errorInfo}',\n [ErrorCode.TOKEN_UPDATE_NO_TOKEN]:\n 'FCM returned no token when updating the user to push.',\n [ErrorCode.USE_SW_AFTER_GET_TOKEN]:\n 'The useServiceWorker() method may only be called once and must be ' +\n 'called before calling getToken() to ensure your service worker is used.',\n [ErrorCode.INVALID_SW_REGISTRATION]:\n 'The input to useServiceWorker() must be a ServiceWorkerRegistration.',\n [ErrorCode.INVALID_BG_HANDLER]:\n 'The input to setBackgroundMessageHandler() must be a function.',\n [ErrorCode.INVALID_VAPID_KEY]: 'The public VAPID key must be a string.',\n [ErrorCode.USE_VAPID_KEY_AFTER_GET_TOKEN]:\n 'The usePublicVapidKey() method may only be called once and must be ' +\n 'called before calling getToken() to ensure your VAPID key is used.'\n};\n\ninterface ErrorParams {\n [ErrorCode.MISSING_APP_CONFIG_VALUES]: {\n valueName: string;\n };\n [ErrorCode.FAILED_DEFAULT_REGISTRATION]: { browserErrorMessage: string };\n [ErrorCode.TOKEN_SUBSCRIBE_FAILED]: { errorInfo: string };\n [ErrorCode.TOKEN_UNSUBSCRIBE_FAILED]: { errorInfo: string };\n [ErrorCode.TOKEN_UPDATE_FAILED]: { errorInfo: string };\n}\n\nexport const ERROR_FACTORY = new ErrorFactory(\n 'messaging',\n 'Messaging',\n ERROR_MAP\n);\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { DEFAULT_VAPID_KEY, ENDPOINT } from '../util/constants';\nimport { ERROR_FACTORY, ErrorCode } from '../util/errors';\nimport { SubscriptionOptions, TokenDetails } from '../interfaces/token-details';\n\nimport { AppConfig } from '../interfaces/app-config';\nimport { FirebaseInternalDependencies } from '../interfaces/internal-dependencies';\n\nexport interface ApiResponse {\n token?: string;\n error?: { message: string };\n}\n\nexport interface ApiRequestBody {\n web: {\n endpoint: string;\n p256dh: string;\n auth: string;\n applicationPubKey?: string;\n };\n}\n\nexport async function requestGetToken(\n firebaseDependencies: FirebaseInternalDependencies,\n subscriptionOptions: SubscriptionOptions\n): Promise {\n const headers = await getHeaders(firebaseDependencies);\n const body = getBody(subscriptionOptions);\n\n const subscribeOptions = {\n method: 'POST',\n headers,\n body: JSON.stringify(body)\n };\n\n let responseData: ApiResponse;\n try {\n const response = await fetch(\n getEndpoint(firebaseDependencies.appConfig),\n subscribeOptions\n );\n responseData = await response.json();\n } catch (err) {\n throw ERROR_FACTORY.create(ErrorCode.TOKEN_SUBSCRIBE_FAILED, {\n errorInfo: (err as Error)?.toString()\n });\n }\n\n if (responseData.error) {\n const message = responseData.error.message;\n throw ERROR_FACTORY.create(ErrorCode.TOKEN_SUBSCRIBE_FAILED, {\n errorInfo: message\n });\n }\n\n if (!responseData.token) {\n throw ERROR_FACTORY.create(ErrorCode.TOKEN_SUBSCRIBE_NO_TOKEN);\n }\n\n return responseData.token;\n}\n\nexport async function requestUpdateToken(\n firebaseDependencies: FirebaseInternalDependencies,\n tokenDetails: TokenDetails\n): Promise {\n const headers = await getHeaders(firebaseDependencies);\n const body = getBody(tokenDetails.subscriptionOptions!);\n\n const updateOptions = {\n method: 'PATCH',\n headers,\n body: JSON.stringify(body)\n };\n\n let responseData: ApiResponse;\n try {\n const response = await fetch(\n `${getEndpoint(firebaseDependencies.appConfig)}/${tokenDetails.token}`,\n updateOptions\n );\n responseData = await response.json();\n } catch (err) {\n throw ERROR_FACTORY.create(ErrorCode.TOKEN_UPDATE_FAILED, {\n errorInfo: (err as Error)?.toString()\n });\n }\n\n if (responseData.error) {\n const message = responseData.error.message;\n throw ERROR_FACTORY.create(ErrorCode.TOKEN_UPDATE_FAILED, {\n errorInfo: message\n });\n }\n\n if (!responseData.token) {\n throw ERROR_FACTORY.create(ErrorCode.TOKEN_UPDATE_NO_TOKEN);\n }\n\n return responseData.token;\n}\n\nexport async function requestDeleteToken(\n firebaseDependencies: FirebaseInternalDependencies,\n token: string\n): Promise {\n const headers = await getHeaders(firebaseDependencies);\n\n const unsubscribeOptions = {\n method: 'DELETE',\n headers\n };\n\n try {\n const response = await fetch(\n `${getEndpoint(firebaseDependencies.appConfig)}/${token}`,\n unsubscribeOptions\n );\n const responseData: ApiResponse = await response.json();\n if (responseData.error) {\n const message = responseData.error.message;\n throw ERROR_FACTORY.create(ErrorCode.TOKEN_UNSUBSCRIBE_FAILED, {\n errorInfo: message\n });\n }\n } catch (err) {\n throw ERROR_FACTORY.create(ErrorCode.TOKEN_UNSUBSCRIBE_FAILED, {\n errorInfo: (err as Error)?.toString()\n });\n }\n}\n\nfunction getEndpoint({ projectId }: AppConfig): string {\n return `${ENDPOINT}/projects/${projectId!}/registrations`;\n}\n\nasync function getHeaders({\n appConfig,\n installations\n}: FirebaseInternalDependencies): Promise {\n const authToken = await installations.getToken();\n\n return new Headers({\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n 'x-goog-api-key': appConfig.apiKey!,\n 'x-goog-firebase-installations-auth': `FIS ${authToken}`\n });\n}\n\nfunction getBody({\n p256dh,\n auth,\n endpoint,\n vapidKey\n}: SubscriptionOptions): ApiRequestBody {\n const body: ApiRequestBody = {\n web: {\n endpoint,\n auth,\n p256dh\n }\n };\n\n if (vapidKey !== DEFAULT_VAPID_KEY) {\n body.web.applicationPubKey = vapidKey;\n }\n\n return body;\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { SubscriptionOptions, TokenDetails } from '../interfaces/token-details';\nimport {\n arrayToBase64,\n base64ToArray\n} from '../helpers/array-base64-translator';\nimport { dbGet, dbRemove, dbSet } from './idb-manager';\nimport {\n requestDeleteToken,\n requestGetToken,\n requestUpdateToken\n} from './requests';\n\nimport { FirebaseInternalDependencies } from '../interfaces/internal-dependencies';\nimport { MessagingService } from '../messaging-service';\n\n// UpdateRegistration will be called once every week.\nconst TOKEN_EXPIRATION_MS = 7 * 24 * 60 * 60 * 1000; // 7 days\n\nexport async function getTokenInternal(\n messaging: MessagingService\n): Promise {\n const pushSubscription = await getPushSubscription(\n messaging.swRegistration!,\n messaging.vapidKey!\n );\n\n const subscriptionOptions: SubscriptionOptions = {\n vapidKey: messaging.vapidKey!,\n swScope: messaging.swRegistration!.scope,\n endpoint: pushSubscription.endpoint,\n auth: arrayToBase64(pushSubscription.getKey('auth')!),\n p256dh: arrayToBase64(pushSubscription.getKey('p256dh')!)\n };\n\n const tokenDetails = await dbGet(messaging.firebaseDependencies);\n if (!tokenDetails) {\n // No token, get a new one.\n return getNewToken(messaging.firebaseDependencies, subscriptionOptions);\n } else if (\n !isTokenValid(tokenDetails.subscriptionOptions!, subscriptionOptions)\n ) {\n // Invalid token, get a new one.\n try {\n await requestDeleteToken(\n messaging.firebaseDependencies!,\n tokenDetails.token\n );\n } catch (e) {\n // Suppress errors because of #2364\n console.warn(e);\n }\n\n return getNewToken(messaging.firebaseDependencies!, subscriptionOptions);\n } else if (Date.now() >= tokenDetails.createTime + TOKEN_EXPIRATION_MS) {\n // Weekly token refresh\n return updateToken(messaging, {\n token: tokenDetails.token,\n createTime: Date.now(),\n subscriptionOptions\n });\n } else {\n // Valid token, nothing to do.\n return tokenDetails.token;\n }\n}\n\n/**\n * This method deletes the token from the database, unsubscribes the token from FCM, and unregisters\n * the push subscription if it exists.\n */\nexport async function deleteTokenInternal(\n messaging: MessagingService\n): Promise {\n const tokenDetails = await dbGet(messaging.firebaseDependencies);\n if (tokenDetails) {\n await requestDeleteToken(\n messaging.firebaseDependencies,\n tokenDetails.token\n );\n await dbRemove(messaging.firebaseDependencies);\n }\n\n // Unsubscribe from the push subscription.\n const pushSubscription =\n await messaging.swRegistration!.pushManager.getSubscription();\n if (pushSubscription) {\n return pushSubscription.unsubscribe();\n }\n\n // If there's no SW, consider it a success.\n return true;\n}\n\nasync function updateToken(\n messaging: MessagingService,\n tokenDetails: TokenDetails\n): Promise {\n try {\n const updatedToken = await requestUpdateToken(\n messaging.firebaseDependencies,\n tokenDetails\n );\n\n const updatedTokenDetails: TokenDetails = {\n ...tokenDetails,\n token: updatedToken,\n createTime: Date.now()\n };\n\n await dbSet(messaging.firebaseDependencies, updatedTokenDetails);\n return updatedToken;\n } catch (e) {\n await deleteTokenInternal(messaging);\n throw e;\n }\n}\n\nasync function getNewToken(\n firebaseDependencies: FirebaseInternalDependencies,\n subscriptionOptions: SubscriptionOptions\n): Promise {\n const token = await requestGetToken(\n firebaseDependencies,\n subscriptionOptions\n );\n const tokenDetails: TokenDetails = {\n token,\n createTime: Date.now(),\n subscriptionOptions\n };\n await dbSet(firebaseDependencies, tokenDetails);\n return tokenDetails.token;\n}\n\n/**\n * Gets a PushSubscription for the current user.\n */\nasync function getPushSubscription(\n swRegistration: ServiceWorkerRegistration,\n vapidKey: string\n): Promise {\n const subscription = await swRegistration.pushManager.getSubscription();\n if (subscription) {\n return subscription;\n }\n\n return swRegistration.pushManager.subscribe({\n userVisibleOnly: true,\n // Chrome <= 75 doesn't support base64-encoded VAPID key. For backward compatibility, VAPID key\n // submitted to pushManager#subscribe must be of type Uint8Array.\n applicationServerKey: base64ToArray(vapidKey)\n });\n}\n\n/**\n * Checks if the saved tokenDetails object matches the configuration provided.\n */\nfunction isTokenValid(\n dbOptions: SubscriptionOptions,\n currentOptions: SubscriptionOptions\n): boolean {\n const isVapidKeyEqual = currentOptions.vapidKey === dbOptions.vapidKey;\n const isEndpointEqual = currentOptions.endpoint === dbOptions.endpoint;\n const isAuthEqual = currentOptions.auth === dbOptions.auth;\n const isP256dhEqual = currentOptions.p256dh === dbOptions.p256dh;\n\n return isVapidKeyEqual && isEndpointEqual && isAuthEqual && isP256dhEqual;\n}\n", "/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { MessagePayload } from '../interfaces/public-types';\nimport { MessagePayloadInternal } from '../interfaces/internal-message-payload';\n\nexport function externalizePayload(\n internalPayload: MessagePayloadInternal\n): MessagePayload {\n const payload: MessagePayload = {\n from: internalPayload.from,\n // eslint-disable-next-line camelcase\n collapseKey: internalPayload.collapse_key,\n // eslint-disable-next-line camelcase\n messageId: internalPayload.fcmMessageId\n } as MessagePayload;\n\n propagateNotificationPayload(payload, internalPayload);\n propagateDataPayload(payload, internalPayload);\n propagateFcmOptions(payload, internalPayload);\n\n return payload;\n}\n\nfunction propagateNotificationPayload(\n payload: MessagePayload,\n messagePayloadInternal: MessagePayloadInternal\n): void {\n if (!messagePayloadInternal.notification) {\n return;\n }\n\n payload.notification = {};\n\n const title = messagePayloadInternal.notification!.title;\n if (!!title) {\n payload.notification!.title = title;\n }\n\n const body = messagePayloadInternal.notification!.body;\n if (!!body) {\n payload.notification!.body = body;\n }\n\n const image = messagePayloadInternal.notification!.image;\n if (!!image) {\n payload.notification!.image = image;\n }\n}\n\nfunction propagateDataPayload(\n payload: MessagePayload,\n messagePayloadInternal: MessagePayloadInternal\n): void {\n if (!messagePayloadInternal.data) {\n return;\n }\n\n payload.data = messagePayloadInternal.data as { [key: string]: string };\n}\n\nfunction propagateFcmOptions(\n payload: MessagePayload,\n messagePayloadInternal: MessagePayloadInternal\n): void {\n // fcmOptions.link value is written into notification.click_action. see more in b/232072111\n if (\n !messagePayloadInternal.fcmOptions &&\n !messagePayloadInternal.notification?.click_action\n ) {\n return;\n }\n\n payload.fcmOptions = {};\n\n const link =\n messagePayloadInternal.fcmOptions?.link ??\n messagePayloadInternal.notification?.click_action;\n\n if (!!link) {\n payload.fcmOptions!.link = link;\n }\n\n // eslint-disable-next-line camelcase\n const analyticsLabel = messagePayloadInternal.fcmOptions?.analytics_label;\n if (!!analyticsLabel) {\n payload.fcmOptions!.analyticsLabel = analyticsLabel;\n }\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { CONSOLE_CAMPAIGN_ID } from '../util/constants';\nimport { ConsoleMessageData } from '../interfaces/internal-message-payload';\n\nexport function isConsoleMessage(data: unknown): data is ConsoleMessageData {\n // This message has a campaign ID, meaning it was sent using the Firebase Console.\n return typeof data === 'object' && !!data && CONSOLE_CAMPAIGN_ID in data;\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/** Returns a promise that resolves after given time passes. */\nexport function sleep(ms: number): Promise {\n return new Promise(resolve => {\n setTimeout(resolve, ms);\n });\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n DEFAULT_BACKOFF_TIME_MS,\n EVENT_MESSAGE_DELIVERED,\n FCM_LOG_SOURCE,\n LOG_INTERVAL_IN_MS,\n MAX_NUMBER_OF_EVENTS_PER_LOG_REQUEST,\n MAX_RETRIES,\n MessageType,\n SDK_PLATFORM_WEB\n} from '../util/constants';\nimport {\n FcmEvent,\n LogEvent,\n LogRequest,\n LogResponse\n} from '../interfaces/logging-types';\n\nimport { MessagePayloadInternal } from '../interfaces/internal-message-payload';\nimport { MessagingService } from '../messaging-service';\n\nconst FIRELOG_ENDPOINT = _mergeStrings(\n 'hts/frbslgigp.ogepscmv/ieo/eaylg',\n 'tp:/ieaeogn-agolai.o/1frlglgc/o'\n);\n\nconst FCM_TRANSPORT_KEY = _mergeStrings(\n 'AzSCbw63g1R0nCw85jG8',\n 'Iaya3yLKwmgvh7cF0q4'\n);\n\nexport function startLoggingService(messaging: MessagingService): void {\n if (!messaging.isLogServiceStarted) {\n _processQueue(messaging, LOG_INTERVAL_IN_MS);\n messaging.isLogServiceStarted = true;\n }\n}\n\n/**\n *\n * @param messaging the messaging instance.\n * @param offsetInMs this method execute after `offsetInMs` elapsed .\n */\nexport function _processQueue(\n messaging: MessagingService,\n offsetInMs: number\n): void {\n setTimeout(async () => {\n if (!messaging.deliveryMetricsExportedToBigQueryEnabled) {\n // flush events and terminate logging service\n messaging.logEvents = [];\n messaging.isLogServiceStarted = false;\n\n return;\n }\n\n if (!messaging.logEvents.length) {\n return _processQueue(messaging, LOG_INTERVAL_IN_MS);\n }\n\n await _dispatchLogEvents(messaging);\n }, offsetInMs);\n}\n\nexport async function _dispatchLogEvents(\n messaging: MessagingService\n): Promise {\n for (\n let i = 0, n = messaging.logEvents.length;\n i < n;\n i += MAX_NUMBER_OF_EVENTS_PER_LOG_REQUEST\n ) {\n const logRequest = _createLogRequest(\n messaging.logEvents.slice(i, i + MAX_NUMBER_OF_EVENTS_PER_LOG_REQUEST)\n );\n\n let retryCount = 0,\n response = {} as Response;\n\n do {\n try {\n response = await fetch(\n FIRELOG_ENDPOINT.concat('?key=', FCM_TRANSPORT_KEY),\n {\n method: 'POST',\n body: JSON.stringify(logRequest)\n }\n );\n\n // don't retry on 200s or non retriable errors\n if (response.ok || (!response.ok && !isRetriableError(response))) {\n break;\n }\n\n if (!response.ok && isRetriableError(response)) {\n // rethrow to retry with quota\n throw new Error(\n 'a retriable Non-200 code is returned in fetch to Firelog endpoint. Retry'\n );\n }\n } catch (error) {\n const isLastAttempt = retryCount === MAX_RETRIES;\n if (isLastAttempt) {\n // existing the do-while interactive retry logic because retry quota has reached.\n break;\n }\n }\n\n let delayInMs: number;\n try {\n delayInMs = Number(\n ((await response.json()) as LogResponse).nextRequestWaitMillis\n );\n } catch (e) {\n delayInMs = DEFAULT_BACKOFF_TIME_MS;\n }\n\n await new Promise(resolve => setTimeout(resolve, delayInMs));\n\n retryCount++;\n } while (retryCount < MAX_RETRIES);\n }\n\n messaging.logEvents = [];\n // schedule for next logging\n _processQueue(messaging, LOG_INTERVAL_IN_MS);\n}\n\nfunction isRetriableError(response: Response): boolean {\n const httpStatus = response.status;\n\n return (\n httpStatus === 429 ||\n httpStatus === 500 ||\n httpStatus === 503 ||\n httpStatus === 504\n );\n}\n\nexport async function stageLog(\n messaging: MessagingService,\n internalPayload: MessagePayloadInternal\n): Promise {\n const fcmEvent = createFcmEvent(\n internalPayload,\n await messaging.firebaseDependencies.installations.getId()\n );\n\n createAndEnqueueLogEvent(messaging, fcmEvent);\n}\n\nfunction createFcmEvent(\n internalPayload: MessagePayloadInternal,\n fid: string\n): FcmEvent {\n const fcmEvent = {} as FcmEvent;\n\n /* eslint-disable camelcase */\n // some fields should always be non-null. Still check to ensure.\n if (!!internalPayload.from) {\n fcmEvent.project_number = internalPayload.from;\n }\n\n if (!!internalPayload.fcmMessageId) {\n fcmEvent.message_id = internalPayload.fcmMessageId;\n }\n\n fcmEvent.instance_id = fid;\n\n if (!!internalPayload.notification) {\n fcmEvent.message_type = MessageType.DISPLAY_NOTIFICATION.toString();\n } else {\n fcmEvent.message_type = MessageType.DATA_MESSAGE.toString();\n }\n\n fcmEvent.sdk_platform = SDK_PLATFORM_WEB.toString();\n fcmEvent.package_name = self.origin.replace(/(^\\w+:|^)\\/\\//, '');\n\n if (!!internalPayload.collapse_key) {\n fcmEvent.collapse_key = internalPayload.collapse_key;\n }\n\n fcmEvent.event = EVENT_MESSAGE_DELIVERED.toString();\n\n if (!!internalPayload.fcmOptions?.analytics_label) {\n fcmEvent.analytics_label = internalPayload.fcmOptions?.analytics_label;\n }\n\n /* eslint-enable camelcase */\n return fcmEvent;\n}\n\nfunction createAndEnqueueLogEvent(\n messaging: MessagingService,\n fcmEvent: FcmEvent\n): void {\n const logEvent = {} as LogEvent;\n\n /* eslint-disable camelcase */\n logEvent.event_time_ms = Math.floor(Date.now()).toString();\n logEvent.source_extension_json_proto3 = JSON.stringify(fcmEvent);\n // eslint-disable-next-line camelcase\n\n messaging.logEvents.push(logEvent);\n}\n\nexport function _createLogRequest(logEventQueue: LogEvent[]): LogRequest {\n const logRequest = {} as LogRequest;\n\n /* eslint-disable camelcase */\n logRequest.log_source = FCM_LOG_SOURCE.toString();\n logRequest.log_event = logEventQueue;\n /* eslint-enable camelcase */\n\n return logRequest;\n}\n\nexport function _mergeStrings(s1: string, s2: string): string {\n const resultArray = [];\n for (let i = 0; i < s1.length; i++) {\n resultArray.push(s1.charAt(i));\n if (i < s2.length) {\n resultArray.push(s2.charAt(i));\n }\n }\n\n return resultArray.join('');\n}\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { DEFAULT_VAPID_KEY, FCM_MSG } from '../util/constants';\nimport {\n MessagePayloadInternal,\n MessageType,\n NotificationPayloadInternal\n} from '../interfaces/internal-message-payload';\nimport {\n NotificationEvent,\n PushEvent,\n PushSubscriptionChangeEvent,\n ServiceWorkerGlobalScope,\n WindowClient\n} from '../util/sw-types';\nimport {\n deleteTokenInternal,\n getTokenInternal\n} from '../internals/token-manager';\n\nimport { MessagingService } from '../messaging-service';\nimport { dbGet } from '../internals/idb-manager';\nimport { externalizePayload } from '../helpers/externalizePayload';\nimport { isConsoleMessage } from '../helpers/is-console-message';\nimport { sleep } from '../helpers/sleep';\nimport { stageLog } from '../helpers/logToFirelog';\n\n// Let TS know that this is a service worker\ndeclare const self: ServiceWorkerGlobalScope;\n\nexport async function onSubChange(\n event: PushSubscriptionChangeEvent,\n messaging: MessagingService\n): Promise {\n const { newSubscription } = event;\n if (!newSubscription) {\n // Subscription revoked, delete token\n await deleteTokenInternal(messaging);\n return;\n }\n\n const tokenDetails = await dbGet(messaging.firebaseDependencies);\n await deleteTokenInternal(messaging);\n\n messaging.vapidKey =\n tokenDetails?.subscriptionOptions?.vapidKey ?? DEFAULT_VAPID_KEY;\n await getTokenInternal(messaging);\n}\n\nexport async function onPush(\n event: PushEvent,\n messaging: MessagingService\n): Promise {\n const internalPayload = getMessagePayloadInternal(event);\n if (!internalPayload) {\n // Failed to get parsed MessagePayload from the PushEvent. Skip handling the push.\n return;\n }\n\n // log to Firelog with user consent\n if (messaging.deliveryMetricsExportedToBigQueryEnabled) {\n await stageLog(messaging, internalPayload);\n }\n\n // foreground handling: eventually passed to onMessage hook\n const clientList = await getClientList();\n if (hasVisibleClients(clientList)) {\n return sendMessagePayloadInternalToWindows(clientList, internalPayload);\n }\n\n // background handling: display if possible and pass to onBackgroundMessage hook\n if (!!internalPayload.notification) {\n await showNotification(wrapInternalPayload(internalPayload));\n }\n\n if (!messaging) {\n return;\n }\n\n if (!!messaging.onBackgroundMessageHandler) {\n const payload = externalizePayload(internalPayload);\n\n if (typeof messaging.onBackgroundMessageHandler === 'function') {\n await messaging.onBackgroundMessageHandler(payload);\n } else {\n messaging.onBackgroundMessageHandler.next(payload);\n }\n }\n}\n\nexport async function onNotificationClick(\n event: NotificationEvent\n): Promise {\n const internalPayload: MessagePayloadInternal =\n event.notification?.data?.[FCM_MSG];\n\n if (!internalPayload) {\n return;\n } else if (event.action) {\n // User clicked on an action button. This will allow developers to act on action button clicks\n // by using a custom onNotificationClick listener that they define.\n return;\n }\n\n // Prevent other listeners from receiving the event\n event.stopImmediatePropagation();\n event.notification.close();\n\n // Note clicking on a notification with no link set will focus the Chrome's current tab.\n const link = getLink(internalPayload);\n if (!link) {\n return;\n }\n\n // FM should only open/focus links from app's origin.\n const url = new URL(link, self.location.href);\n const originUrl = new URL(self.location.origin);\n\n if (url.host !== originUrl.host) {\n return;\n }\n\n let client = await getWindowClient(url);\n\n if (!client) {\n client = await self.clients.openWindow(link);\n\n // Wait three seconds for the client to initialize and set up the message handler so that it\n // can receive the message.\n await sleep(3000);\n } else {\n client = await client.focus();\n }\n\n if (!client) {\n // Window Client will not be returned if it's for a third party origin.\n return;\n }\n\n internalPayload.messageType = MessageType.NOTIFICATION_CLICKED;\n internalPayload.isFirebaseMessaging = true;\n return client.postMessage(internalPayload);\n}\n\nfunction wrapInternalPayload(\n internalPayload: MessagePayloadInternal\n): NotificationPayloadInternal {\n const wrappedInternalPayload: NotificationPayloadInternal = {\n ...(internalPayload.notification as unknown as NotificationPayloadInternal)\n };\n\n // Put the message payload under FCM_MSG name so we can identify the notification as being an FCM\n // notification vs a notification from somewhere else (i.e. normal web push or developer generated\n // notification).\n wrappedInternalPayload.data = {\n [FCM_MSG]: internalPayload\n };\n\n return wrappedInternalPayload;\n}\n\nfunction getMessagePayloadInternal({\n data\n}: PushEvent): MessagePayloadInternal | null {\n if (!data) {\n return null;\n }\n\n try {\n return data.json();\n } catch (err) {\n // Not JSON so not an FCM message.\n return null;\n }\n}\n\n/**\n * @param url The URL to look for when focusing a client.\n * @return Returns an existing window client or a newly opened WindowClient.\n */\nasync function getWindowClient(url: URL): Promise {\n const clientList = await getClientList();\n\n for (const client of clientList) {\n const clientUrl = new URL(client.url, self.location.href);\n\n if (url.host === clientUrl.host) {\n return client;\n }\n }\n\n return null;\n}\n\n/**\n * @returns If there is currently a visible WindowClient, this method will resolve to true,\n * otherwise false.\n */\nfunction hasVisibleClients(clientList: WindowClient[]): boolean {\n return clientList.some(\n client =>\n client.visibilityState === 'visible' &&\n // Ignore chrome-extension clients as that matches the background pages of extensions, which\n // are always considered visible for some reason.\n !client.url.startsWith('chrome-extension://')\n );\n}\n\nfunction sendMessagePayloadInternalToWindows(\n clientList: WindowClient[],\n internalPayload: MessagePayloadInternal\n): void {\n internalPayload.isFirebaseMessaging = true;\n internalPayload.messageType = MessageType.PUSH_RECEIVED;\n\n for (const client of clientList) {\n client.postMessage(internalPayload);\n }\n}\n\nfunction getClientList(): Promise {\n return self.clients.matchAll({\n type: 'window',\n includeUncontrolled: true\n // TS doesn't know that \"type: 'window'\" means it'll return WindowClient[]\n }) as Promise;\n}\n\nfunction showNotification(\n notificationPayloadInternal: NotificationPayloadInternal\n): Promise {\n // Note: Firefox does not support the maxActions property.\n // https://developer.mozilla.org/en-US/docs/Web/API/notification/maxActions\n const { actions } = notificationPayloadInternal;\n const { maxActions } = Notification;\n if (actions && maxActions && actions.length > maxActions) {\n console.warn(\n `This browser only supports ${maxActions} actions. The remaining actions will not be displayed.`\n );\n }\n\n return self.registration.showNotification(\n /* title= */ notificationPayloadInternal.title ?? '',\n notificationPayloadInternal\n );\n}\n\nfunction getLink(payload: MessagePayloadInternal): string | null {\n // eslint-disable-next-line camelcase\n const link = payload.fcmOptions?.link ?? payload.notification?.click_action;\n if (link) {\n return link;\n }\n\n if (isConsoleMessage(payload.data)) {\n // Notification created in the Firebase Console. Redirect to origin.\n return self.location.origin;\n } else {\n return null;\n }\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ERROR_FACTORY, ErrorCode } from '../util/errors';\nimport { FirebaseApp, FirebaseOptions } from '@firebase/app';\n\nimport { AppConfig } from '../interfaces/app-config';\nimport { FirebaseError } from '@firebase/util';\n\nexport function extractAppConfig(app: FirebaseApp): AppConfig {\n if (!app || !app.options) {\n throw getMissingValueError('App Configuration Object');\n }\n\n if (!app.name) {\n throw getMissingValueError('App Name');\n }\n\n // Required app config keys\n const configKeys: ReadonlyArray = [\n 'projectId',\n 'apiKey',\n 'appId',\n 'messagingSenderId'\n ];\n\n const { options } = app;\n for (const keyName of configKeys) {\n if (!options[keyName]) {\n throw getMissingValueError(keyName);\n }\n }\n\n return {\n appName: app.name,\n projectId: options.projectId!,\n apiKey: options.apiKey!,\n appId: options.appId!,\n senderId: options.messagingSenderId!\n };\n}\n\nfunction getMissingValueError(valueName: string): FirebaseError {\n return ERROR_FACTORY.create(ErrorCode.MISSING_APP_CONFIG_VALUES, {\n valueName\n });\n}\n", "/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { FirebaseApp, _FirebaseService } from '@firebase/app';\nimport { MessagePayload, NextFn, Observer } from './interfaces/public-types';\n\nimport { FirebaseAnalyticsInternalName } from '@firebase/analytics-interop-types';\nimport { FirebaseInternalDependencies } from './interfaces/internal-dependencies';\nimport { LogEvent } from './interfaces/logging-types';\nimport { Provider } from '@firebase/component';\nimport { _FirebaseInstallationsInternal } from '@firebase/installations';\nimport { extractAppConfig } from './helpers/extract-app-config';\n\nexport class MessagingService implements _FirebaseService {\n readonly app!: FirebaseApp;\n readonly firebaseDependencies!: FirebaseInternalDependencies;\n\n swRegistration?: ServiceWorkerRegistration;\n vapidKey?: string;\n // logging is only done with end user consent. Default to false.\n deliveryMetricsExportedToBigQueryEnabled: boolean = false;\n\n onBackgroundMessageHandler:\n | NextFn\n | Observer\n | null = null;\n\n onMessageHandler: NextFn | Observer | null =\n null;\n\n logEvents: LogEvent[] = [];\n isLogServiceStarted: boolean = false;\n\n constructor(\n app: FirebaseApp,\n installations: _FirebaseInstallationsInternal,\n analyticsProvider: Provider\n ) {\n const appConfig = extractAppConfig(app);\n\n this.firebaseDependencies = {\n app,\n appConfig,\n installations,\n analyticsProvider\n };\n }\n\n _delete(): Promise {\n return Promise.resolve();\n }\n}\n", "/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n Component,\n ComponentContainer,\n ComponentType,\n InstanceFactory\n} from '@firebase/component';\nimport {\n onNotificationClick,\n onPush,\n onSubChange\n} from '../listeners/sw-listeners';\n\nimport { GetTokenOptions } from '../interfaces/public-types';\nimport { MessagingInternal } from '@firebase/messaging-interop-types';\nimport { MessagingService } from '../messaging-service';\nimport { ServiceWorkerGlobalScope } from '../util/sw-types';\nimport { _registerComponent, registerVersion } from '@firebase/app';\nimport { getToken } from '../api/getToken';\nimport { messageEventListener } from '../listeners/window-listener';\n\nimport { name, version } from '../../package.json';\n\nconst WindowMessagingFactory: InstanceFactory<'messaging'> = (\n container: ComponentContainer\n) => {\n const messaging = new MessagingService(\n container.getProvider('app').getImmediate(),\n container.getProvider('installations-internal').getImmediate(),\n container.getProvider('analytics-internal')\n );\n\n navigator.serviceWorker.addEventListener('message', e =>\n messageEventListener(messaging as MessagingService, e)\n );\n\n return messaging;\n};\n\nconst WindowMessagingInternalFactory: InstanceFactory<'messaging-internal'> = (\n container: ComponentContainer\n) => {\n const messaging = container\n .getProvider('messaging')\n .getImmediate() as MessagingService;\n\n const messagingInternal: MessagingInternal = {\n getToken: (options?: GetTokenOptions) => getToken(messaging, options)\n };\n\n return messagingInternal;\n};\n\ndeclare const self: ServiceWorkerGlobalScope;\nconst SwMessagingFactory: InstanceFactory<'messaging'> = (\n container: ComponentContainer\n) => {\n const messaging = new MessagingService(\n container.getProvider('app').getImmediate(),\n container.getProvider('installations-internal').getImmediate(),\n container.getProvider('analytics-internal')\n );\n\n self.addEventListener('push', e => {\n e.waitUntil(onPush(e, messaging as MessagingService));\n });\n self.addEventListener('pushsubscriptionchange', e => {\n e.waitUntil(onSubChange(e, messaging as MessagingService));\n });\n self.addEventListener('notificationclick', e => {\n e.waitUntil(onNotificationClick(e));\n });\n\n return messaging;\n};\n\nexport function registerMessagingInWindow(): void {\n _registerComponent(\n new Component('messaging', WindowMessagingFactory, ComponentType.PUBLIC)\n );\n\n _registerComponent(\n new Component(\n 'messaging-internal',\n WindowMessagingInternalFactory,\n ComponentType.PRIVATE\n )\n );\n\n registerVersion(name, version);\n // BUILD_TARGET will be replaced by values like esm5, esm2017, cjs5, etc during the compilation\n registerVersion(name, version, '__BUILD_TARGET__');\n}\n\n/**\n * The messaging instance registered in sw is named differently than that of in client. This is\n * because both `registerMessagingInWindow` and `registerMessagingInSw` would be called in\n * `messaging-compat` and component with the same name can only be registered once.\n */\nexport function registerMessagingInSw(): void {\n _registerComponent(\n new Component('messaging-sw', SwMessagingFactory, ComponentType.PUBLIC)\n );\n}\n", "/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n areCookiesEnabled,\n isIndexedDBAvailable,\n validateIndexedDBOpenable\n} from '@firebase/util';\n\n/**\n * Checks if all required APIs exist in the browser.\n * @returns a Promise that resolves to a boolean.\n *\n * @public\n */\nexport async function isWindowSupported(): Promise {\n try {\n // This throws if open() is unsupported, so adding it to the conditional\n // statement below can cause an uncaught error.\n await validateIndexedDBOpenable();\n } catch (e) {\n return false;\n }\n // firebase-js-sdk/issues/2393 reveals that idb#open in Safari iframe and Firefox private browsing\n // might be prohibited to run. In these contexts, an error would be thrown during the messaging\n // instantiating phase, informing the developers to import/call isSupported for special handling.\n return (\n typeof window !== 'undefined' &&\n isIndexedDBAvailable() &&\n areCookiesEnabled() &&\n 'serviceWorker' in navigator &&\n 'PushManager' in window &&\n 'Notification' in window &&\n 'fetch' in window &&\n ServiceWorkerRegistration.prototype.hasOwnProperty('showNotification') &&\n PushSubscription.prototype.hasOwnProperty('getKey')\n );\n}\n\n/**\n * Checks whether all required APIs exist within SW Context\n * @returns a Promise that resolves to a boolean.\n *\n * @public\n */\nexport async function isSwSupported(): Promise {\n // firebase-js-sdk/issues/2393 reveals that idb#open in Safari iframe and Firefox private browsing\n // might be prohibited to run. In these contexts, an error would be thrown during the messaging\n // instantiating phase, informing the developers to import/call isSupported for special handling.\n return (\n isIndexedDBAvailable() &&\n (await validateIndexedDBOpenable()) &&\n 'PushManager' in self &&\n 'Notification' in self &&\n ServiceWorkerRegistration.prototype.hasOwnProperty('showNotification') &&\n PushSubscription.prototype.hasOwnProperty('getKey')\n );\n}\n", "/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ERROR_FACTORY, ErrorCode } from '../util/errors';\n\nimport {\n MessagePayload,\n NextFn,\n Observer,\n Unsubscribe\n} from '../interfaces/public-types';\nimport { MessagingService } from '../messaging-service';\n\nexport function onBackgroundMessage(\n messaging: MessagingService,\n nextOrObserver: NextFn | Observer\n): Unsubscribe {\n if (self.document !== undefined) {\n throw ERROR_FACTORY.create(ErrorCode.AVAILABLE_IN_SW);\n }\n\n messaging.onBackgroundMessageHandler = nextOrObserver;\n\n return () => {\n messaging.onBackgroundMessageHandler = null;\n };\n}\n", "/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Messaging } from '../interfaces/public-types';\nimport { MessagingService } from '../messaging-service';\n\nexport function _setDeliveryMetricsExportedToBigQueryEnabled(\n messaging: Messaging,\n enable: boolean\n): void {\n (messaging as MessagingService).deliveryMetricsExportedToBigQueryEnabled =\n enable;\n}\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ERROR_FACTORY, ErrorCode } from './util/errors';\nimport { FirebaseApp, _getProvider, getApp } from '@firebase/app';\nimport {\n GetTokenOptions,\n MessagePayload,\n Messaging\n} from './interfaces/public-types';\nimport {\n NextFn,\n Observer,\n Unsubscribe,\n getModularInstance\n} from '@firebase/util';\nimport { isSwSupported, isWindowSupported } from './api/isSupported';\n\nimport { MessagingService } from './messaging-service';\nimport { deleteToken as _deleteToken } from './api/deleteToken';\nimport { getToken as _getToken } from './api/getToken';\nimport { onBackgroundMessage as _onBackgroundMessage } from './api/onBackgroundMessage';\nimport { onMessage as _onMessage } from './api/onMessage';\nimport { _setDeliveryMetricsExportedToBigQueryEnabled } from './api/setDeliveryMetricsExportedToBigQueryEnabled';\n\n/**\n * Retrieves a Firebase Cloud Messaging instance.\n *\n * @returns The Firebase Cloud Messaging instance associated with the provided firebase app.\n *\n * @public\n */\nexport function getMessagingInWindow(app: FirebaseApp = getApp()): Messaging {\n // Conscious decision to make this async check non-blocking during the messaging instance\n // initialization phase for performance consideration. An error would be thrown latter for\n // developer's information. Developers can then choose to import and call `isSupported` for\n // special handling.\n isWindowSupported().then(\n isSupported => {\n // If `isWindowSupported()` resolved, but returned false.\n if (!isSupported) {\n throw ERROR_FACTORY.create(ErrorCode.UNSUPPORTED_BROWSER);\n }\n },\n _ => {\n // If `isWindowSupported()` rejected.\n throw ERROR_FACTORY.create(ErrorCode.INDEXED_DB_UNSUPPORTED);\n }\n );\n return _getProvider(getModularInstance(app), 'messaging').getImmediate();\n}\n\n/**\n * Retrieves a Firebase Cloud Messaging instance.\n *\n * @returns The Firebase Cloud Messaging instance associated with the provided firebase app.\n *\n * @public\n */\nexport function getMessagingInSw(app: FirebaseApp = getApp()): Messaging {\n // Conscious decision to make this async check non-blocking during the messaging instance\n // initialization phase for performance consideration. An error would be thrown latter for\n // developer's information. Developers can then choose to import and call `isSupported` for\n // special handling.\n isSwSupported().then(\n isSupported => {\n // If `isSwSupported()` resolved, but returned false.\n if (!isSupported) {\n throw ERROR_FACTORY.create(ErrorCode.UNSUPPORTED_BROWSER);\n }\n },\n _ => {\n // If `isSwSupported()` rejected.\n throw ERROR_FACTORY.create(ErrorCode.INDEXED_DB_UNSUPPORTED);\n }\n );\n return _getProvider(getModularInstance(app), 'messaging-sw').getImmediate();\n}\n\n/**\n * Subscribes the {@link Messaging} instance to push notifications. Returns an Firebase Cloud\n * Messaging registration token that can be used to send push messages to that {@link Messaging}\n * instance.\n *\n * If a notification permission isn't already granted, this method asks the user for permission. The\n * returned promise rejects if the user does not allow the app to show notifications.\n *\n * @param messaging - The {@link Messaging} instance.\n * @param options - Provides an optional vapid key and an optinoal service worker registration\n *\n * @returns The promise resolves with an FCM registration token.\n *\n * @public\n */\nexport async function getToken(\n messaging: Messaging,\n options?: GetTokenOptions\n): Promise {\n messaging = getModularInstance(messaging);\n return _getToken(messaging as MessagingService, options);\n}\n\n/**\n * Deletes the registration token associated with this {@link Messaging} instance and unsubscribes\n * the {@link Messaging} instance from the push subscription.\n *\n * @param messaging - The {@link Messaging} instance.\n *\n * @returns The promise resolves when the token has been successfully deleted.\n *\n * @public\n */\nexport function deleteToken(messaging: Messaging): Promise {\n messaging = getModularInstance(messaging);\n return _deleteToken(messaging as MessagingService);\n}\n\n/**\n * When a push message is received and the user is currently on a page for your origin, the\n * message is passed to the page and an `onMessage()` event is dispatched with the payload of\n * the push message.\n *\n *\n * @param messaging - The {@link Messaging} instance.\n * @param nextOrObserver - This function, or observer object with `next` defined,\n * is called when a message is received and the user is currently viewing your page.\n * @returns To stop listening for messages execute this returned function.\n *\n * @public\n */\nexport function onMessage(\n messaging: Messaging,\n nextOrObserver: NextFn | Observer\n): Unsubscribe {\n messaging = getModularInstance(messaging);\n return _onMessage(messaging as MessagingService, nextOrObserver);\n}\n\n/**\n * Called when a message is received while the app is in the background. An app is considered to be\n * in the background if no active window is displayed.\n *\n * @param messaging - The {@link Messaging} instance.\n * @param nextOrObserver - This function, or observer object with `next` defined, is called when a\n * message is received and the app is currently in the background.\n *\n * @returns To stop listening for messages execute this returned function\n *\n * @public\n */\nexport function onBackgroundMessage(\n messaging: Messaging,\n nextOrObserver: NextFn | Observer\n): Unsubscribe {\n messaging = getModularInstance(messaging);\n return _onBackgroundMessage(messaging as MessagingService, nextOrObserver);\n}\n\n/**\n * Enables or disables Firebase Cloud Messaging message delivery metrics export to BigQuery. By\n * default, message delivery metrics are not exported to BigQuery. Use this method to enable or\n * disable the export at runtime.\n *\n * @param messaging - The `FirebaseMessaging` instance.\n * @param enable - Whether Firebase Cloud Messaging should export message delivery metrics to\n * BigQuery.\n *\n * @public\n */\nexport function experimentalSetDeliveryMetricsExportedToBigQueryEnabled(\n messaging: Messaging,\n enable: boolean\n): void {\n messaging = getModularInstance(messaging);\n return _setDeliveryMetricsExportedToBigQueryEnabled(messaging, enable);\n}\n", "/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport '@firebase/installations';\n\nimport { Messaging } from './interfaces/public-types';\nimport { registerMessagingInSw } from './helpers/register';\n\nexport * from './interfaces/public-types';\nexport {\n onBackgroundMessage,\n getMessagingInSw as getMessaging,\n experimentalSetDeliveryMetricsExportedToBigQueryEnabled\n} from './api';\nexport { isSwSupported as isSupported } from './api/isSupported';\n\ndeclare module '@firebase/component' {\n interface NameServiceMapping {\n 'messaging-sw': Messaging;\n }\n}\n\nregisterMessagingInSw();\n", "import { initializeApp } from 'firebase/app';\nimport {\n experimentalSetDeliveryMetricsExportedToBigQueryEnabled,\n getMessaging,\n isSupported,\n onBackgroundMessage\n} from 'firebase/messaging/sw';\n\ndeclare var self: ServiceWorkerGlobalScope;\n\nself.addEventListener('install', (event) => {\n console.log(self);\n console.log(event);\n});\n\nconst app = initializeApp({\n apiKey: 'AIzaSyAgUhHU8wSJgO5MVNy95tMT07NEjzMOfz0',\n authDomain: 'react-native-firebase-testing.firebaseapp.com',\n databaseURL: 'https://react-native-firebase-testing.firebaseio.com',\n projectId: 'react-native-firebase-testing',\n storageBucket: 'react-native-firebase-testing.appspot.com',\n messagingSenderId: '448618578101',\n appId: '1:448618578101:web:ecaffe2bc4511738',\n});\n\nisSupported().then((isSupported) => {\n if (isSupported) {\n const messaging = getMessaging(app);\n\n experimentalSetDeliveryMetricsExportedToBigQueryEnabled(messaging, true);\n\n console.log('experimental working');\n\n onBackgroundMessage(messaging, ({ notification: notification }) => {\n const { title, body, image } = notification ?? {};\n\n if (!title) {\n return;\n }\n\n self.registration.showNotification(title, {\n body,\n icon: image || '/assets/icons/icon-72x72.png',\n });\n });\n }\n});\n"], - "mappings": "AEiBA,IAAMA,GAAoB,SAAUC,EAAW,CAE7C,IAAMC,EAAgB,CAAA,EAClBC,EAAI,EACR,QAASC,EAAI,EAAGA,EAAIH,EAAI,OAAQG,IAAK,CACnC,IAAIC,EAAIJ,EAAI,WAAWG,CAAC,EACpBC,EAAI,IACNH,EAAIC,KAAOE,EACFA,EAAI,MACbH,EAAIC,KAAQE,GAAK,EAAK,IACtBH,EAAIC,KAAQE,EAAI,GAAM,MAErBA,EAAI,SAAY,OACjBD,EAAI,EAAIH,EAAI,SACXA,EAAI,WAAWG,EAAI,CAAC,EAAI,SAAY,OAGrCC,EAAI,QAAYA,EAAI,OAAW,KAAOJ,EAAI,WAAW,EAAEG,CAAC,EAAI,MAC5DF,EAAIC,KAAQE,GAAK,GAAM,IACvBH,EAAIC,KAASE,GAAK,GAAM,GAAM,IAC9BH,EAAIC,KAASE,GAAK,EAAK,GAAM,IAC7BH,EAAIC,KAAQE,EAAI,GAAM,MAEtBH,EAAIC,KAAQE,GAAK,GAAM,IACvBH,EAAIC,KAASE,GAAK,EAAK,GAAM,IAC7BH,EAAIC,KAAQE,EAAI,GAAM,IAEzB,CACD,OAAOH,CACT,EAQMI,GAAoB,SAAUC,EAAe,CAEjD,IAAML,EAAgB,CAAA,EAClBM,EAAM,EACRH,EAAI,EACN,KAAOG,EAAMD,EAAM,QAAQ,CACzB,IAAME,EAAKF,EAAMC,KACjB,GAAIC,EAAK,IACPP,EAAIG,KAAO,OAAO,aAAaI,CAAE,UACxBA,EAAK,KAAOA,EAAK,IAAK,CAC/B,IAAMC,EAAKH,EAAMC,KACjBN,EAAIG,KAAO,OAAO,cAAeI,EAAK,KAAO,EAAMC,EAAK,EAAG,CAC5D,SAAUD,EAAK,KAAOA,EAAK,IAAK,CAE/B,IAAMC,EAAKH,EAAMC,KACXG,EAAKJ,EAAMC,KACXI,EAAKL,EAAMC,KACX,IACDC,EAAK,IAAM,IAAQC,EAAK,KAAO,IAAQC,EAAK,KAAO,EAAMC,EAAK,IACjE,MACFV,EAAIG,KAAO,OAAO,aAAa,OAAU,GAAK,GAAG,EACjDH,EAAIG,KAAO,OAAO,aAAa,OAAU,EAAI,KAAK,CACnD,KAAM,CACL,IAAMK,EAAKH,EAAMC,KACXG,EAAKJ,EAAMC,KACjBN,EAAIG,KAAO,OAAO,cACdI,EAAK,KAAO,IAAQC,EAAK,KAAO,EAAMC,EAAK,EAAG,CAEnD,CACF,CACD,OAAOT,EAAI,KAAK,EAAE,CACpB,EAqBaW,GAAiB,CAI5B,eAAgB,KAKhB,eAAgB,KAMhB,sBAAuB,KAMvB,sBAAuB,KAMvB,kBACE,iEAKF,IAAI,cAAY,CACd,OAAO,KAAK,kBAAoB,OAMlC,IAAI,sBAAoB,CACtB,OAAO,KAAK,kBAAoB,OAUlC,mBAAoB,OAAO,MAAS,WAWpC,gBAAgBC,EAA8BC,EAAiB,CAC7D,GAAI,CAAC,MAAM,QAAQD,CAAK,EACtB,MAAM,MAAM,+CAA+C,EAG7D,KAAK,MAAK,EAEV,IAAME,EAAgBD,EAClB,KAAK,sBACL,KAAK,eAEHE,EAAS,CAAA,EAEf,QAAS,EAAI,EAAG,EAAIH,EAAM,OAAQ,GAAK,EAAG,CACxC,IAAMI,EAAQJ,EAAM,GACdK,EAAY,EAAI,EAAIL,EAAM,OAC1BM,EAAQD,EAAYL,EAAM,EAAI,GAAK,EACnCO,EAAY,EAAI,EAAIP,EAAM,OAC1BQ,EAAQD,EAAYP,EAAM,EAAI,GAAK,EAEnCS,EAAWL,GAAS,EACpBM,GAAaN,EAAQ,IAAS,EAAME,GAAS,EAC/CK,GAAaL,EAAQ,KAAS,EAAME,GAAS,EAC7CI,EAAWJ,EAAQ,GAElBD,IACHK,EAAW,GAENP,IACHM,EAAW,KAIfR,EAAO,KACLD,EAAcO,GACdP,EAAcQ,GACdR,EAAcS,GACdT,EAAcU,EAAS,CAE1B,CAED,OAAOT,EAAO,KAAK,EAAE,GAWvB,aAAaH,EAAeC,EAAiB,CAG3C,OAAI,KAAK,oBAAsB,CAACA,EACvB,KAAKD,CAAK,EAEZ,KAAK,gBAAgBd,GAAkBc,CAAK,EAAGC,CAAO,GAW/D,aAAaD,EAAeC,EAAgB,CAG1C,OAAI,KAAK,oBAAsB,CAACA,EACvB,KAAKD,CAAK,EAEZR,GAAkB,KAAK,wBAAwBQ,EAAOC,CAAO,CAAC,GAkBvE,wBAAwBD,EAAeC,EAAgB,CACrD,KAAK,MAAK,EAEV,IAAMY,EAAgBZ,EAClB,KAAK,sBACL,KAAK,eAEHE,EAAmB,CAAA,EAEzB,QAAS,EAAI,EAAG,EAAIH,EAAM,QAAU,CAClC,IAAMI,EAAQS,EAAcb,EAAM,OAAO,GAAG,GAGtCM,EADY,EAAIN,EAAM,OACFa,EAAcb,EAAM,OAAO,CAAC,GAAK,EAC3D,EAAE,EAGF,IAAMQ,EADY,EAAIR,EAAM,OACFa,EAAcb,EAAM,OAAO,CAAC,GAAK,GAC3D,EAAE,EAGF,IAAMc,EADY,EAAId,EAAM,OACFa,EAAcb,EAAM,OAAO,CAAC,GAAK,GAG3D,GAFA,EAAE,EAEEI,GAAS,MAAQE,GAAS,MAAQE,GAAS,MAAQM,GAAS,KAC9D,MAAM,MAAK,EAGb,IAAML,EAAYL,GAAS,EAAME,GAAS,EAG1C,GAFAH,EAAO,KAAKM,CAAQ,EAEhBD,IAAU,GAAI,CAChB,IAAME,EAAaJ,GAAS,EAAK,IAASE,GAAS,EAGnD,GAFAL,EAAO,KAAKO,CAAQ,EAEhBI,IAAU,GAAI,CAChB,IAAMH,GAAaH,GAAS,EAAK,IAAQM,EACzCX,EAAO,KAAKQ,EAAQ,CACrB,CACF,CACF,CAED,OAAOR,GAQT,OAAK,CACH,GAAI,CAAC,KAAK,eAAgB,CACxB,KAAK,eAAiB,CAAA,EACtB,KAAK,eAAiB,CAAA,EACtB,KAAK,sBAAwB,CAAA,EAC7B,KAAK,sBAAwB,CAAA,EAG7B,QAASb,EAAI,EAAGA,EAAI,KAAK,aAAa,OAAQA,IAC5C,KAAK,eAAeA,GAAK,KAAK,aAAa,OAAOA,CAAC,EACnD,KAAK,eAAe,KAAK,eAAeA,IAAMA,EAC9C,KAAK,sBAAsBA,GAAK,KAAK,qBAAqB,OAAOA,CAAC,EAClE,KAAK,sBAAsB,KAAK,sBAAsBA,IAAMA,EAGxDA,GAAK,KAAK,kBAAkB,SAC9B,KAAK,eAAe,KAAK,qBAAqB,OAAOA,CAAC,GAAKA,EAC3D,KAAK,sBAAsB,KAAK,aAAa,OAAOA,CAAC,GAAKA,EAG/D,IAOQyB,GAAe,SAAU5B,EAAW,CAC/C,IAAM6B,EAAY9B,GAAkBC,CAAG,EACvC,OAAOY,GAAO,gBAAgBiB,EAAW,EAAI,CAC/C,EAMaC,EAAgC,SAAU9B,EAAW,CAEhE,OAAO4B,GAAa5B,CAAG,EAAE,QAAQ,MAAO,EAAE,CAC5C,ME7Ua+B,OAAQ,CAInB,aAAA,CAFA,KAAA,OAAoC,IAAK,CAAA,EACzC,KAAA,QAAqC,IAAK,CAAA,EAExC,KAAK,QAAU,IAAI,QAAQ,CAACC,EAASC,IAAU,CAC7C,KAAK,QAAUD,EACf,KAAK,OAASC,CAChB,CAAC,EAQH,aACEC,EAAqD,CAErD,MAAO,CAACC,EAAOC,IAAU,CACnBD,EACF,KAAK,OAAOA,CAAK,EAEjB,KAAK,QAAQC,CAAK,EAEhB,OAAOF,GAAa,aAGtB,KAAK,QAAQ,MAAM,IAAK,CAAA,CAAG,EAIvBA,EAAS,SAAW,EACtBA,EAASC,CAAK,EAEdD,EAASC,EAAOC,CAAK,EAG3B,EAEH,WEoFeC,GAAoB,CAClC,OAAO,OAAO,WAAc,QAC9B,UASgBC,GAAyB,CACvC,OAAO,IAAI,QAAQ,CAACC,EAASC,IAAU,CACrC,GAAI,CACF,IAAIC,EAAoB,GAClBC,EACJ,0DACIC,EAAU,KAAK,UAAU,KAAKD,CAAa,EACjDC,EAAQ,UAAY,IAAK,CACvBA,EAAQ,OAAO,MAAK,EAEfF,GACH,KAAK,UAAU,eAAeC,CAAa,EAE7CH,EAAQ,EAAI,CACd,EACAI,EAAQ,gBAAkB,IAAK,CAC7BF,EAAW,EACb,EAEAE,EAAQ,QAAU,IAAK,OACrBH,IAAOI,EAAAD,EAAQ,SAAK,MAAAC,IAAA,OAAA,OAAAA,EAAE,UAAW,EAAE,CACrC,CACD,OAAQC,EAAP,CACAL,EAAOK,CAAK,CACb,CACH,CAAC,CACH,CCrHA,IAAMC,GAAa,gBAYNC,EAAP,cAA6B,KAAK,CAItC,YAEWC,EACTC,EAEOC,EAAoC,CAE3C,MAAMD,CAAO,EALJ,KAAI,KAAJD,EAGF,KAAU,WAAVE,EAPA,KAAI,KAAWJ,GAatB,OAAO,eAAe,KAAMC,EAAc,SAAS,EAI/C,MAAM,mBACR,MAAM,kBAAkB,KAAMI,EAAa,UAAU,MAAM,EAGhE,EAEYA,OAAY,CAIvB,YACmBC,EACAC,EACAC,EAA2B,CAF3B,KAAO,QAAPF,EACA,KAAW,YAAXC,EACA,KAAM,OAANC,EAGnB,OACEN,KACGO,EAAyD,CAE5D,IAAML,EAAcK,EAAK,IAAoB,CAAA,EACvCC,EAAW,GAAG,KAAK,WAAWR,IAC9BS,EAAW,KAAK,OAAOT,GAEvBC,EAAUQ,EAAWC,GAAgBD,EAAUP,CAAU,EAAI,QAE7DS,EAAc,GAAG,KAAK,gBAAgBV,MAAYO,MAIxD,OAFc,IAAIT,EAAcS,EAAUG,EAAaT,CAAU,EAIpE,EAED,SAASQ,GAAgBD,EAAkBF,EAAe,CACxD,OAAOE,EAAS,QAAQG,GAAS,CAACC,EAAGC,IAAO,CAC1C,IAAMC,EAAQR,EAAKO,GACnB,OAAOC,GAAS,KAAO,OAAOA,CAAK,EAAI,IAAID,KAC7C,CAAC,CACH,CAEA,IAAMF,GAAU,gBG3EA,SAAAI,EAAUC,EAAWC,EAAS,CAC5C,GAAID,IAAMC,EACR,MAAO,GAGT,IAAMC,EAAQ,OAAO,KAAKF,CAAC,EACrBG,EAAQ,OAAO,KAAKF,CAAC,EAC3B,QAAWG,KAAKF,EAAO,CACrB,GAAI,CAACC,EAAM,SAASC,CAAC,EACnB,MAAO,GAGT,IAAMC,EAASL,EAA8BI,GACvCE,EAASL,EAA8BG,GAC7C,GAAIG,GAASF,CAAK,GAAKE,GAASD,CAAK,GACnC,GAAI,CAACP,EAAUM,EAAOC,CAAK,EACzB,MAAO,WAEAD,IAAUC,EACnB,MAAO,EAEV,CAED,QAAWF,KAAKD,EACd,GAAI,CAACD,EAAM,SAASE,CAAC,EACnB,MAAO,GAGX,MAAO,EACT,CAEA,SAASG,GAASC,EAAc,CAC9B,OAAOA,IAAU,MAAQ,OAAOA,GAAU,QAC5C,CQ1DO,IAAMC,GAAmB,EAAI,GAAK,GAAK,IEZxC,SAAUC,EACdC,EAAwC,CAExC,OAAIA,GAAYA,EAA+B,UACrCA,EAA+B,UAEhCA,CAEX,KCDaC,OAAS,CAiBpB,YACWC,EACAC,EACAC,EAAmB,CAFnB,KAAI,KAAJF,EACA,KAAe,gBAAfC,EACA,KAAI,KAAJC,EAnBX,KAAiB,kBAAG,GAIpB,KAAY,aAAe,CAAA,EAE3B,KAAA,kBAA2C,OAE3C,KAAiB,kBAAwC,KAczD,qBAAqBC,EAAuB,CAC1C,YAAK,kBAAoBA,EAClB,KAGT,qBAAqBC,EAA0B,CAC7C,YAAK,kBAAoBA,EAClB,KAGT,gBAAgBC,EAAiB,CAC/B,YAAK,aAAeA,EACb,KAGT,2BAA2BC,EAAsC,CAC/D,YAAK,kBAAoBA,EAClB,KAEV,ECrDM,IAAMC,EAAqB,gBCgBrBC,OAAQ,CAWnB,YACmBR,EACAS,EAA6B,CAD7B,KAAI,KAAJT,EACA,KAAS,UAATS,EAZX,KAAS,UAAwB,KACxB,KAAA,UAAgD,IAAI,IACpD,KAAA,kBAGb,IAAI,IACS,KAAA,iBACf,IAAI,IACE,KAAA,gBAAuD,IAAI,IAWnE,IAAIC,EAAmB,CAErB,IAAMC,EAAuB,KAAK,4BAA4BD,CAAU,EAExE,GAAI,CAAC,KAAK,kBAAkB,IAAIC,CAAoB,EAAG,CACrD,IAAMC,EAAW,IAAIC,EAGrB,GAFA,KAAK,kBAAkB,IAAIF,EAAsBC,CAAQ,EAGvD,KAAK,cAAcD,CAAoB,GACvC,KAAK,qBAAoB,EAGzB,GAAI,CACF,IAAMG,EAAW,KAAK,uBAAuB,CAC3C,mBAAoBH,CACrB,CAAA,EACGG,GACFF,EAAS,QAAQE,CAAQ,CAE5B,MAAC,CAGD,CAEJ,CAED,OAAO,KAAK,kBAAkB,IAAIH,CAAoB,EAAG,QAmB3D,aAAaI,EAGZ,OAEC,IAAMJ,EAAuB,KAAK,4BAChCI,GAAS,UAAU,EAEfC,GAAWC,EAAAF,GAAS,YAAY,MAAAE,IAAA,OAAAA,EAAA,GAEtC,GACE,KAAK,cAAcN,CAAoB,GACvC,KAAK,qBAAoB,EAEzB,GAAI,CACF,OAAO,KAAK,uBAAuB,CACjC,mBAAoBA,CACrB,CAAA,CACF,OAAQO,EAAP,CACA,GAAIF,EACF,OAAO,KAEP,MAAME,CAET,KACI,CAEL,GAAIF,EACF,OAAO,KAEP,MAAM,MAAM,WAAW,KAAK,uBAAuB,CAEtD,EAGH,cAAY,CACV,OAAO,KAAK,UAGd,aAAaG,EAAuB,CAClC,GAAIA,EAAU,OAAS,KAAK,KAC1B,MAAM,MACJ,yBAAyBA,EAAU,qBAAqB,KAAK,OAAO,EAIxE,GAAI,KAAK,UACP,MAAM,MAAM,iBAAiB,KAAK,gCAAgC,EAMpE,GAHA,KAAK,UAAYA,EAGb,EAAC,KAAK,qBAAoB,EAK9B,IAAIC,GAAiBD,CAAS,EAC5B,GAAI,CACF,KAAK,uBAAuB,CAAE,mBAAoBZ,CAAkB,CAAE,CACvE,MAAC,CAKD,CAMH,OAAW,CACTc,EACAC,CAAgB,IACb,KAAK,kBAAkB,QAAO,EAAI,CACrC,IAAMX,EACJ,KAAK,4BAA4BU,CAAkB,EAErD,GAAI,CAEF,IAAMP,EAAW,KAAK,uBAAuB,CAC3C,mBAAoBH,CACrB,CAAA,EACDW,EAAiB,QAAQR,CAAQ,CAClC,MAAC,CAGD,CACF,GAGH,cAAcJ,EAAqBH,EAAkB,CACnD,KAAK,kBAAkB,OAAOG,CAAU,EACxC,KAAK,iBAAiB,OAAOA,CAAU,EACvC,KAAK,UAAU,OAAOA,CAAU,EAKlC,MAAM,QAAM,CACV,IAAMa,EAAW,MAAM,KAAK,KAAK,UAAU,OAAM,CAAE,EAEnD,MAAM,QAAQ,IAAI,CAChB,GAAGA,EACA,OAAOC,GAAW,aAAcA,CAAO,EAEvC,IAAIA,GAAYA,EAAgB,SAAU,OAAM,CAAE,EACrD,GAAGD,EACA,OAAOC,GAAW,YAAaA,CAAO,EAEtC,IAAIA,GAAYA,EAAgB,QAAO,CAAE,CAC7C,CAAA,EAGH,gBAAc,CACZ,OAAO,KAAK,WAAa,KAG3B,cAAcd,EAAqBH,EAAkB,CACnD,OAAO,KAAK,UAAU,IAAIG,CAAU,EAGtC,WAAWA,EAAqBH,EAAkB,CAChD,OAAO,KAAK,iBAAiB,IAAIG,CAAU,GAAK,CAAA,EAGlD,WAAWe,EAA0B,CAAA,EAAE,CACrC,GAAM,CAAE,QAAAV,EAAU,CAAA,CAAE,EAAKU,EACnBd,EAAuB,KAAK,4BAChCc,EAAK,kBAAkB,EAEzB,GAAI,KAAK,cAAcd,CAAoB,EACzC,MAAM,MACJ,GAAG,KAAK,QAAQA,iCAAoD,EAIxE,GAAI,CAAC,KAAK,eAAc,EACtB,MAAM,MAAM,aAAa,KAAK,kCAAkC,EAGlE,IAAMG,EAAW,KAAK,uBAAuB,CAC3C,mBAAoBH,EACpB,QAAAI,CACD,CAAA,EAGD,OAAW,CACTM,EACAC,CAAgB,IACb,KAAK,kBAAkB,QAAO,EAAI,CACrC,IAAMI,EACJ,KAAK,4BAA4BL,CAAkB,EACjDV,IAAyBe,GAC3BJ,EAAiB,QAAQR,CAAQ,CAEpC,CAED,OAAOA,EAWT,OAAOR,EAA6BI,EAAmB,OACrD,IAAMC,EAAuB,KAAK,4BAA4BD,CAAU,EAClEiB,GACJV,EAAA,KAAK,gBAAgB,IAAIN,CAAoB,KAAC,MAAAM,IAAA,OAAAA,EAC9C,IAAI,IACNU,EAAkB,IAAIrB,CAAQ,EAC9B,KAAK,gBAAgB,IAAIK,EAAsBgB,CAAiB,EAEhE,IAAMC,EAAmB,KAAK,UAAU,IAAIjB,CAAoB,EAChE,OAAIiB,GACFtB,EAASsB,EAAkBjB,CAAoB,EAG1C,IAAK,CACVgB,EAAkB,OAAOrB,CAAQ,CACnC,EAOM,sBACNQ,EACAJ,EAAkB,CAElB,IAAMmB,EAAY,KAAK,gBAAgB,IAAInB,CAAU,EACrD,GAAI,EAACmB,EAGL,QAAWvB,KAAYuB,EACrB,GAAI,CACFvB,EAASQ,EAAUJ,CAAU,CAC9B,MAAC,CAED,EAIG,uBAAuB,CAC7B,mBAAAW,EACA,QAAAN,EAAU,CAAA,CAAE,EAIb,CACC,IAAID,EAAW,KAAK,UAAU,IAAIO,CAAkB,EACpD,GAAI,CAACP,GAAY,KAAK,YACpBA,EAAW,KAAK,UAAU,gBAAgB,KAAK,UAAW,CACxD,mBAAoBgB,GAA8BT,CAAkB,EACpE,QAAAN,CACD,CAAA,EACD,KAAK,UAAU,IAAIM,EAAoBP,CAAQ,EAC/C,KAAK,iBAAiB,IAAIO,EAAoBN,CAAO,EAOrD,KAAK,sBAAsBD,EAAUO,CAAkB,EAOnD,KAAK,UAAU,mBACjB,GAAI,CACF,KAAK,UAAU,kBACb,KAAK,UACLA,EACAP,CAAQ,CAEX,MAAC,CAED,CAIL,OAAOA,GAAY,KAGb,4BACNJ,EAAqBH,EAAkB,CAEvC,OAAI,KAAK,UACA,KAAK,UAAU,kBAAoBG,EAAaH,EAEhDG,EAIH,sBAAoB,CAC1B,MACE,CAAC,CAAC,KAAK,WACP,KAAK,UAAU,oBAAiB,WAGrC,EAGD,SAASoB,GAA8BpB,EAAkB,CACvD,OAAOA,IAAeH,EAAqB,OAAYG,CACzD,CAEA,SAASU,GAAiCD,EAAuB,CAC/D,OAAOA,EAAU,oBAAiB,OACpC,KCjWaY,OAAkB,CAG7B,YAA6B/B,EAAY,CAAZ,KAAI,KAAJA,EAFZ,KAAA,UAAY,IAAI,IAajC,aAA6BmB,EAAuB,CAClD,IAAMa,EAAW,KAAK,YAAYb,EAAU,IAAI,EAChD,GAAIa,EAAS,eAAc,EACzB,MAAM,IAAI,MACR,aAAab,EAAU,yCAAyC,KAAK,MAAM,EAI/Ea,EAAS,aAAab,CAAS,EAGjC,wBAAwCA,EAAuB,CAC5C,KAAK,YAAYA,EAAU,IAAI,EACnC,eAAc,GAEzB,KAAK,UAAU,OAAOA,EAAU,IAAI,EAGtC,KAAK,aAAaA,CAAS,EAU7B,YAA4BnB,EAAO,CACjC,GAAI,KAAK,UAAU,IAAIA,CAAI,EACzB,OAAO,KAAK,UAAU,IAAIA,CAAI,EAIhC,IAAMgC,EAAW,IAAIxB,EAAYR,EAAM,IAAI,EAC3C,YAAK,UAAU,IAAIA,EAAMgC,CAAqC,EAEvDA,EAGT,cAAY,CACV,OAAO,MAAM,KAAK,KAAK,UAAU,OAAM,CAAE,EAE5C,ECxCM,IAAMC,GAAsB,CAAA,EAavBC,GAAZ,SAAYA,EAAQ,CAClBA,EAAAA,EAAA,MAAA,GAAA,QACAA,EAAAA,EAAA,QAAA,GAAA,UACAA,EAAAA,EAAA,KAAA,GAAA,OACAA,EAAAA,EAAA,KAAA,GAAA,OACAA,EAAAA,EAAA,MAAA,GAAA,QACAA,EAAAA,EAAA,OAAA,GAAA,QACF,GAPYA,IAAAA,EAOX,CAAA,EAAA,EAED,IAAMC,GAA2D,CAC/D,MAASD,EAAS,MAClB,QAAWA,EAAS,QACpB,KAAQA,EAAS,KACjB,KAAQA,EAAS,KACjB,MAASA,EAAS,MAClB,OAAUA,EAAS,QAMfE,GAA4BF,EAAS,KAmBrCG,GAAgB,CACpB,CAACH,EAAS,OAAQ,MAClB,CAACA,EAAS,SAAU,MACpB,CAACA,EAAS,MAAO,OACjB,CAACA,EAAS,MAAO,OACjB,CAACA,EAAS,OAAQ,SAQdI,GAAgC,CAACC,EAAUC,KAAYC,IAAc,CACzE,GAAID,EAAUD,EAAS,SACrB,OAEF,IAAMG,EAAM,IAAI,KAAI,EAAG,YAAW,EAC5BC,EAASN,GAAcG,GAC7B,GAAIG,EACF,QAAQA,GACN,IAAID,OAASH,EAAS,QACtB,GAAGE,CAAI,MAGT,OAAM,IAAI,MACR,8DAA8DD,IAAU,CAG9E,EAEaI,OAAM,CAOjB,YAAmBC,EAAY,CAAZ,KAAI,KAAJA,EAUX,KAAS,UAAGT,GAsBZ,KAAW,YAAeE,GAc1B,KAAe,gBAAsB,KA1C3CL,GAAU,KAAK,IAAI,EAQrB,IAAI,UAAQ,CACV,OAAO,KAAK,UAGd,IAAI,SAASa,EAAa,CACxB,GAAI,EAAEA,KAAOZ,GACX,MAAM,IAAI,UAAU,kBAAkBY,6BAA+B,EAEvE,KAAK,UAAYA,EAInB,YAAYA,EAA8B,CACxC,KAAK,UAAY,OAAOA,GAAQ,SAAWX,GAAkBW,GAAOA,EAQtE,IAAI,YAAU,CACZ,OAAO,KAAK,YAEd,IAAI,WAAWA,EAAe,CAC5B,GAAI,OAAOA,GAAQ,WACjB,MAAM,IAAI,UAAU,mDAAmD,EAEzE,KAAK,YAAcA,EAOrB,IAAI,gBAAc,CAChB,OAAO,KAAK,gBAEd,IAAI,eAAeA,EAAsB,CACvC,KAAK,gBAAkBA,EAOzB,SAASL,EAAe,CACtB,KAAK,iBAAmB,KAAK,gBAAgB,KAAMP,EAAS,MAAO,GAAGO,CAAI,EAC1E,KAAK,YAAY,KAAMP,EAAS,MAAO,GAAGO,CAAI,EAEhD,OAAOA,EAAe,CACpB,KAAK,iBACH,KAAK,gBAAgB,KAAMP,EAAS,QAAS,GAAGO,CAAI,EACtD,KAAK,YAAY,KAAMP,EAAS,QAAS,GAAGO,CAAI,EAElD,QAAQA,EAAe,CACrB,KAAK,iBAAmB,KAAK,gBAAgB,KAAMP,EAAS,KAAM,GAAGO,CAAI,EACzE,KAAK,YAAY,KAAMP,EAAS,KAAM,GAAGO,CAAI,EAE/C,QAAQA,EAAe,CACrB,KAAK,iBAAmB,KAAK,gBAAgB,KAAMP,EAAS,KAAM,GAAGO,CAAI,EACzE,KAAK,YAAY,KAAMP,EAAS,KAAM,GAAGO,CAAI,EAE/C,SAASA,EAAe,CACtB,KAAK,iBAAmB,KAAK,gBAAgB,KAAMP,EAAS,MAAO,GAAGO,CAAI,EAC1E,KAAK,YAAY,KAAMP,EAAS,MAAO,GAAGO,CAAI,EAEjD,ECnND,IAAMM,GAAgB,CAACC,EAAQC,IAAiBA,EAAa,KAAMC,GAAMF,aAAkBE,CAAC,EAExFC,GACAC,GAEJ,SAASC,IAAuB,CAC5B,OAAQF,KACHA,GAAoB,CACjB,YACA,eACA,SACA,UACA,cACJ,EACR,CAEA,SAASG,IAA0B,CAC/B,OAAQF,KACHA,GAAuB,CACpB,UAAU,UAAU,QACpB,UAAU,UAAU,SACpB,UAAU,UAAU,kBACxB,EACR,CACA,IAAMG,GAAmB,IAAI,QACvBC,EAAqB,IAAI,QACzBC,GAA2B,IAAI,QAC/BC,EAAiB,IAAI,QACrBC,EAAwB,IAAI,QAClC,SAASC,GAAiBC,EAAS,CAC/B,IAAMC,EAAU,IAAI,QAAQ,CAACC,EAASC,IAAW,CAC7C,IAAMC,EAAW,IAAM,CACnBJ,EAAQ,oBAAoB,UAAWK,CAAO,EAC9CL,EAAQ,oBAAoB,QAASM,CAAK,CAC9C,EACMD,EAAU,IAAM,CAClBH,EAAQK,EAAKP,EAAQ,MAAM,CAAC,EAC5BI,EAAS,CACb,EACME,EAAQ,IAAM,CAChBH,EAAOH,EAAQ,KAAK,EACpBI,EAAS,CACb,EACAJ,EAAQ,iBAAiB,UAAWK,CAAO,EAC3CL,EAAQ,iBAAiB,QAASM,CAAK,CAC3C,CAAC,EACD,OAAAL,EACK,KAAMO,GAAU,CAGbA,aAAiB,WACjBd,GAAiB,IAAIc,EAAOR,CAAO,CAG3C,CAAC,EACI,MAAM,IAAM,CAAE,CAAC,EAGpBF,EAAsB,IAAIG,EAASD,CAAO,EACnCC,CACX,CACA,SAASQ,GAA+BC,EAAI,CAExC,GAAIf,EAAmB,IAAIe,CAAE,EACzB,OACJ,IAAMC,EAAO,IAAI,QAAQ,CAACT,EAASC,IAAW,CAC1C,IAAMC,EAAW,IAAM,CACnBM,EAAG,oBAAoB,WAAYE,CAAQ,EAC3CF,EAAG,oBAAoB,QAASJ,CAAK,EACrCI,EAAG,oBAAoB,QAASJ,CAAK,CACzC,EACMM,EAAW,IAAM,CACnBV,EAAQ,EACRE,EAAS,CACb,EACME,EAAQ,IAAM,CAChBH,EAAOO,EAAG,OAAS,IAAI,aAAa,aAAc,YAAY,CAAC,EAC/DN,EAAS,CACb,EACAM,EAAG,iBAAiB,WAAYE,CAAQ,EACxCF,EAAG,iBAAiB,QAASJ,CAAK,EAClCI,EAAG,iBAAiB,QAASJ,CAAK,CACtC,CAAC,EAEDX,EAAmB,IAAIe,EAAIC,CAAI,CACnC,CACA,IAAIE,EAAgB,CAChB,IAAIC,EAAQC,EAAMC,EAAU,CACxB,GAAIF,aAAkB,eAAgB,CAElC,GAAIC,IAAS,OACT,OAAOpB,EAAmB,IAAImB,CAAM,EAExC,GAAIC,IAAS,mBACT,OAAOD,EAAO,kBAAoBlB,GAAyB,IAAIkB,CAAM,EAGzE,GAAIC,IAAS,QACT,OAAOC,EAAS,iBAAiB,GAC3B,OACAA,EAAS,YAAYA,EAAS,iBAAiB,EAAE,CAE/D,CAEA,OAAOT,EAAKO,EAAOC,EAAK,CAC5B,EACA,IAAID,EAAQC,EAAMP,EAAO,CACrB,OAAAM,EAAOC,GAAQP,EACR,EACX,EACA,IAAIM,EAAQC,EAAM,CACd,OAAID,aAAkB,iBACjBC,IAAS,QAAUA,IAAS,SACtB,GAEJA,KAAQD,CACnB,CACJ,EACA,SAASG,GAAaC,EAAU,CAC5BL,EAAgBK,EAASL,CAAa,CAC1C,CACA,SAASM,GAAaC,EAAM,CAIxB,OAAIA,IAAS,YAAY,UAAU,aAC/B,EAAE,qBAAsB,eAAe,WAChC,SAAUC,KAAeC,EAAM,CAClC,IAAMZ,EAAKU,EAAK,KAAKG,EAAO,IAAI,EAAGF,EAAY,GAAGC,CAAI,EACtD,OAAA1B,GAAyB,IAAIc,EAAIW,EAAW,KAAOA,EAAW,KAAK,EAAI,CAACA,CAAU,CAAC,EAC5Ed,EAAKG,CAAE,CAClB,EAOAjB,GAAwB,EAAE,SAAS2B,CAAI,EAChC,YAAaE,EAAM,CAGtB,OAAAF,EAAK,MAAMG,EAAO,IAAI,EAAGD,CAAI,EACtBf,EAAKb,GAAiB,IAAI,IAAI,CAAC,CAC1C,EAEG,YAAa4B,EAAM,CAGtB,OAAOf,EAAKa,EAAK,MAAMG,EAAO,IAAI,EAAGD,CAAI,CAAC,CAC9C,CACJ,CACA,SAASE,GAAuBhB,EAAO,CACnC,OAAI,OAAOA,GAAU,WACVW,GAAaX,CAAK,GAGzBA,aAAiB,gBACjBC,GAA+BD,CAAK,EACpCtB,GAAcsB,EAAOhB,GAAqB,CAAC,EACpC,IAAI,MAAMgB,EAAOK,CAAa,EAElCL,EACX,CACA,SAASD,EAAKC,EAAO,CAGjB,GAAIA,aAAiB,WACjB,OAAOT,GAAiBS,CAAK,EAGjC,GAAIX,EAAe,IAAIW,CAAK,EACxB,OAAOX,EAAe,IAAIW,CAAK,EACnC,IAAMiB,EAAWD,GAAuBhB,CAAK,EAG7C,OAAIiB,IAAajB,IACbX,EAAe,IAAIW,EAAOiB,CAAQ,EAClC3B,EAAsB,IAAI2B,EAAUjB,CAAK,GAEtCiB,CACX,CACA,IAAMF,EAAUf,GAAUV,EAAsB,IAAIU,CAAK,EC5KzD,SAASkB,EAAOC,EAAMC,EAAS,CAAE,QAAAC,EAAS,QAAAC,EAAS,SAAAC,EAAU,WAAAC,CAAW,EAAI,CAAC,EAAG,CAC5E,IAAMC,EAAU,UAAU,KAAKN,EAAMC,CAAO,EACtCM,EAAcC,EAAKF,CAAO,EAChC,OAAIH,GACAG,EAAQ,iBAAiB,gBAAkBG,GAAU,CACjDN,EAAQK,EAAKF,EAAQ,MAAM,EAAGG,EAAM,WAAYA,EAAM,WAAYD,EAAKF,EAAQ,WAAW,CAAC,CAC/F,CAAC,EAEDJ,GACAI,EAAQ,iBAAiB,UAAW,IAAMJ,EAAQ,CAAC,EACvDK,EACK,KAAMG,GAAO,CACVL,GACAK,EAAG,iBAAiB,QAAS,IAAML,EAAW,CAAC,EAC/CD,GACAM,EAAG,iBAAiB,gBAAiB,IAAMN,EAAS,CAAC,CAC7D,CAAC,EACI,MAAM,IAAM,CAAE,CAAC,EACbG,CACX,CAMA,SAASI,EAASX,EAAM,CAAE,QAAAE,CAAQ,EAAI,CAAC,EAAG,CACtC,IAAMI,EAAU,UAAU,eAAeN,CAAI,EAC7C,OAAIE,GACAI,EAAQ,iBAAiB,UAAW,IAAMJ,EAAQ,CAAC,EAChDM,EAAKF,CAAO,EAAE,KAAK,IAAG,EAAY,CAC7C,CAEA,IAAMM,GAAc,CAAC,MAAO,SAAU,SAAU,aAAc,OAAO,EAC/DC,GAAe,CAAC,MAAO,MAAO,SAAU,OAAO,EAC/CC,GAAgB,IAAI,IAC1B,SAASC,GAAUC,EAAQC,EAAM,CAC7B,GAAI,EAAED,aAAkB,aACpB,EAAEC,KAAQD,IACV,OAAOC,GAAS,UAChB,OAEJ,GAAIH,GAAc,IAAIG,CAAI,EACtB,OAAOH,GAAc,IAAIG,CAAI,EACjC,IAAMC,EAAiBD,EAAK,QAAQ,aAAc,EAAE,EAC9CE,EAAWF,IAASC,EACpBE,EAAUP,GAAa,SAASK,CAAc,EACpD,GAEA,EAAEA,KAAmBC,EAAW,SAAW,gBAAgB,YACvD,EAAEC,GAAWR,GAAY,SAASM,CAAc,GAChD,OAEJ,IAAMG,EAAS,eAAgBC,KAAcC,EAAM,CAE/C,IAAMC,EAAK,KAAK,YAAYF,EAAWF,EAAU,YAAc,UAAU,EACrEJ,EAASQ,EAAG,MAChB,OAAIL,IACAH,EAASA,EAAO,MAAMO,EAAK,MAAM,CAAC,IAM9B,MAAM,QAAQ,IAAI,CACtBP,EAAOE,GAAgB,GAAGK,CAAI,EAC9BH,GAAWI,EAAG,IAClB,CAAC,GAAG,EACR,EACA,OAAAV,GAAc,IAAIG,EAAMI,CAAM,EACvBA,CACX,CACAI,GAAcC,IAAc,CACxB,GAAGA,EACH,IAAK,CAACV,EAAQC,EAAMU,IAAaZ,GAAUC,EAAQC,CAAI,GAAKS,EAAS,IAAIV,EAAQC,EAAMU,CAAQ,EAC/F,IAAK,CAACX,EAAQC,IAAS,CAAC,CAACF,GAAUC,EAAQC,CAAI,GAAKS,EAAS,IAAIV,EAAQC,CAAI,CACjF,EAAE,MC5DWW,QAAyB,CACpC,YAA6BC,EAA6B,CAA7B,KAAS,UAATA,EAG7B,uBAAqB,CAInB,OAHkB,KAAK,UAAU,aAAY,EAI1C,IAAIC,GAAW,CACd,GAAIC,GAAyBD,CAAQ,EAAG,CACtC,IAAME,EAAUF,EAAS,aAAY,EACrC,MAAO,GAAGE,EAAQ,WAAWA,EAAQ,SACtC,KACC,QAAO,IAEX,CAAC,EACA,OAAOC,GAAaA,CAAS,EAC7B,KAAK,GAAG,EAEd,EASD,SAASF,GAAyBD,EAAwB,CACxD,IAAMI,EAAYJ,EAAS,aAAY,EACvC,OAAOI,GAAW,OAAI,SACxB,oCCtCO,IAAMC,EAAS,IAAIC,EAAO,eAAe,iqBC6BzC,IAAMC,GAAqB,YAErBC,GAAsB,CACjC,CAACC,IAAU,YACX,CAACC,IAAgB,mBACjB,CAACC,IAAgB,iBACjB,CAACC,IAAsB,wBACvB,CAACC,IAAe,iBAChB,CAACC,IAAqB,wBACtB,CAACC,IAAW,YACZ,CAACC,IAAiB,mBAClB,CAACC,IAAe,YAChB,CAACC,IAAqB,mBACtB,CAACC,IAAgB,UACjB,CAACC,IAAsB,iBACvB,CAACC,IAAoB,WACrB,CAACC,IAA0B,kBAC3B,CAACC,IAAgB,WACjB,CAACC,IAAsB,kBACvB,CAACC,IAAkB,YACnB,CAACC,IAAwB,mBACzB,CAACC,IAAmB,UACpB,CAACC,IAAyB,iBAC1B,CAACC,IAAc,WACf,CAACC,IAAoB,kBACrB,CAACC,IAAgB,WACjB,CAACC,IAAsB,kBACvB,UAAW,UACX,CAACC,IAAc,eClDJ,IAAAC,EAAQ,IAAI,IAQZC,GAAc,IAAI,IAOf,SAAAC,GACdC,EACAC,EAAuB,CAEvB,GAAI,CACDD,EAAwB,UAAU,aAAaC,CAAS,CAC1D,OAAQC,EAAP,CACAC,EAAO,MACL,aAAaF,EAAU,4CAA4CD,EAAI,OACvEE,CAAC,CAEJ,CACH,CAoBM,SAAUE,EACdC,EAAuB,CAEvB,IAAMC,EAAgBD,EAAU,KAChC,GAAIE,GAAY,IAAID,CAAa,EAC/B,OAAAE,EAAO,MACL,sDAAsDF,IAAgB,EAGjE,GAGTC,GAAY,IAAID,EAAeD,CAAS,EAGxC,QAAWI,KAAOC,EAAM,OAAM,EAC5BC,GAAcF,EAAwBJ,CAAS,EAGjD,MAAO,EACT,CAWgB,SAAAO,EACdH,EACAI,EAAO,CAEP,IAAMC,EAAuBL,EAAwB,UAClD,YAAY,WAAW,EACvB,aAAa,CAAE,SAAU,EAAI,CAAE,EAClC,OAAIK,GACGA,EAAoB,iBAAgB,EAEnCL,EAAwB,UAAU,YAAYI,CAAI,CAC5D,CCnFA,IAAME,GAA6B,CACjC,CAAA,UACE,oFAEF,CAAA,gBAAyB,gCACzB,CAAA,iBACE,kFACF,CAAA,eAAwB,kDACxB,CAAA,wBACE,6EAEF,CAAA,wBACE,wDACF,CAAA,YACE,gFACF,CAAA,WACE,qFACF,CAAA,WACE,mFACF,CAAA,cACE,uFAeSC,EAAgB,IAAIC,EAC/B,MACA,WACAF,EAAM,MCzCKG,QAAe,CAc1B,YACEC,EACAC,EACAC,EAA6B,CANvB,KAAU,WAAG,GAQnB,KAAK,SAAgB,OAAA,OAAA,CAAA,EAAAF,CAAO,EAC5B,KAAK,QAAe,OAAA,OAAA,CAAA,EAAAC,CAAM,EAC1B,KAAK,MAAQA,EAAO,KACpB,KAAK,gCACHA,EAAO,+BACT,KAAK,WAAaC,EAClB,KAAK,UAAU,aACb,IAAIC,EAAU,MAAO,IAAM,KAAI,QAAA,CAAuB,EAI1D,IAAI,gCAA8B,CAChC,YAAK,eAAc,EACZ,KAAK,gCAGd,IAAI,+BAA+BC,EAAY,CAC7C,KAAK,eAAc,EACnB,KAAK,gCAAkCA,EAGzC,IAAI,MAAI,CACN,YAAK,eAAc,EACZ,KAAK,MAGd,IAAI,SAAO,CACT,YAAK,eAAc,EACZ,KAAK,SAGd,IAAI,QAAM,CACR,YAAK,eAAc,EACZ,KAAK,QAGd,IAAI,WAAS,CACX,OAAO,KAAK,WAGd,IAAI,WAAS,CACX,OAAO,KAAK,WAGd,IAAI,UAAUA,EAAY,CACxB,KAAK,WAAaA,EAOZ,gBAAc,CACpB,GAAI,KAAK,UACP,MAAMP,EAAc,OAAM,cAAuB,CAAE,QAAS,KAAK,KAAK,CAAE,EAG7E,WCOeQ,GACdC,EACAC,EAAY,CAAA,EAAE,CAEV,OAAOA,GAAc,WAEvBA,EAAY,CAAE,KADDA,CACK,GAGpB,IAAMC,EAAM,OAAA,OAAA,CACV,KAAMC,GACN,+BAAgC,EAAK,EAClCF,CAAS,EAERG,EAAOF,EAAO,KAEpB,GAAI,OAAOE,GAAS,UAAY,CAACA,EAC/B,MAAMC,EAAc,OAA8B,eAAA,CAChD,QAAS,OAAOD,CAAI,CACrB,CAAA,EAGH,IAAME,EAAcC,EAAM,IAAIH,CAAI,EAClC,GAAIE,EAAa,CAEf,GACEE,EAAUR,EAASM,EAAY,OAAO,GACtCE,EAAUN,EAAQI,EAAY,MAAM,EAEpC,OAAOA,EAEP,MAAMD,EAAc,OAA+B,gBAAA,CAAE,QAASD,CAAI,CAAE,CAEvE,CAED,IAAMK,EAAY,IAAIC,EAAmBN,CAAI,EAC7C,QAAWO,KAAaC,GAAY,OAAM,EACxCH,EAAU,aAAaE,CAAS,EAGlC,IAAME,EAAS,IAAIC,GAAgBd,EAASE,EAAQO,CAAS,EAE7D,OAAAF,EAAM,IAAIH,EAAMS,CAAM,EAEfA,CACT,CA+BgB,SAAAE,GAAOX,EAAeD,GAAkB,CACtD,IAAMa,EAAMT,EAAM,IAAIH,CAAI,EAC1B,GAAI,CAACY,EACH,MAAMX,EAAc,OAAwB,SAAA,CAAE,QAASD,CAAI,CAAE,EAG/D,OAAOY,CACT,UAgDgBC,EACdC,EACAC,EACAC,EAAgB,OAIhB,IAAIC,GAAUC,EAAAC,GAAoBL,MAAqB,MAAAI,IAAA,OAAAA,EAAAJ,EACnDE,IACFC,GAAW,IAAID,KAEjB,IAAMI,EAAkBH,EAAQ,MAAM,OAAO,EACvCI,EAAkBN,EAAQ,MAAM,OAAO,EAC7C,GAAIK,GAAmBC,EAAiB,CACtC,IAAMC,EAAU,CACd,+BAA+BL,oBAA0BF,OAEvDK,GACFE,EAAQ,KACN,iBAAiBL,oDAA0D,EAG3EG,GAAmBC,GACrBC,EAAQ,KAAK,KAAK,EAEhBD,GACFC,EAAQ,KACN,iBAAiBP,oDAA0D,EAG/EQ,EAAO,KAAKD,EAAQ,KAAK,GAAG,CAAC,EAC7B,MACD,CACDE,EACE,IAAIC,EACF,GAAGR,YACH,KAAO,CAAE,QAAAA,EAAS,QAAAF,CAAO,GAAG,SAAA,CAE7B,CAEL,CCnQA,IAAMW,GAAU,8BACVC,GAAa,EACbC,EAAa,2BASfC,GAAiD,KACrD,SAASC,IAAY,CACnB,OAAKD,KACHA,GAAYE,EAAcL,GAASC,GAAY,CAC7C,QAAS,CAACK,EAAIC,IAAc,CAM1B,OAAQA,EAAU,CAChB,IAAK,GACHD,EAAG,kBAAkBJ,CAAU,CAClC,EAEJ,CAAA,EAAE,MAAM,GAAI,CACX,MAAMM,EAAc,OAA0B,WAAA,CAC5C,qBAAsB,EAAE,OACzB,CAAA,CACH,CAAC,GAEIL,EACT,CAEO,eAAeM,GACpBC,EAAgB,OAEhB,GAAI,CAEF,OADW,MAAMN,GAAY,GAE1B,YAAYF,CAAU,EACtB,YAAYA,CAAU,EACtB,IAAIS,GAAWD,CAAG,CAAC,CACvB,OAAQE,EAAP,CACA,GAAIA,aAAaC,EACfC,EAAO,KAAKF,EAAE,OAAO,MAChB,CACL,IAAMG,EAAcP,EAAc,OAAyB,UAAA,CACzD,sBAAsBQ,EAACJ,KAAW,MAAAI,IAAA,OAAA,OAAAA,EAAE,OACrC,CAAA,EACDF,EAAO,KAAKC,EAAY,OAAO,CAChC,CACF,CACH,CAEO,eAAeE,GACpBP,EACAQ,EAAsC,OAEtC,GAAI,CAEF,IAAMC,GADK,MAAMf,GAAY,GACf,YAAYF,EAAY,WAAW,EAEjD,aADoBiB,EAAG,YAAYjB,CAAU,EAC3B,IAAIgB,EAAiBP,GAAWD,CAAG,CAAC,EAC/CS,EAAG,IACX,OAAQP,EAAP,CACA,GAAIA,aAAaC,EACfC,EAAO,KAAKF,EAAE,OAAO,MAChB,CACL,IAAMG,EAAcP,EAAc,OAA2B,UAAA,CAC3D,sBAAsBQ,EAACJ,KAAW,MAAAI,IAAA,OAAA,OAAAA,EAAE,OACrC,CAAA,EACDF,EAAO,KAAKC,EAAY,OAAO,CAChC,CACF,CACH,CAEA,SAASJ,GAAWD,EAAgB,CAClC,MAAO,GAAGA,EAAI,QAAQA,EAAI,QAAQ,OACpC,CCpEA,IAAMU,GAAmB,KAEnBC,GAAwC,GAAK,GAAK,GAAK,GAAK,IAErDC,QAAoB,CAyB/B,YAA6BC,EAA6B,CAA7B,KAAS,UAATA,EAT7B,KAAgB,iBAAiC,KAU/C,IAAMb,EAAM,KAAK,UAAU,YAAY,KAAK,EAAE,aAAY,EAC1D,KAAK,SAAW,IAAIc,GAAqBd,CAAG,EAC5C,KAAK,wBAA0B,KAAK,SAAS,KAAI,EAAG,KAAKe,IACvD,KAAK,iBAAmBA,EACjBA,EACR,EAUH,MAAM,kBAAgB,CAOpB,IAAMC,EANiB,KAAK,UACzB,YAAY,iBAAiB,EAC7B,aAAY,EAIc,sBAAqB,EAC5CC,EAAOC,GAAgB,EAM7B,GALI,KAAK,mBAAqB,OAC5B,KAAK,iBAAmB,MAAM,KAAK,yBAKnC,OAAK,iBAAiB,wBAA0BD,GAChD,KAAK,iBAAiB,WAAW,KAC/BE,GAAuBA,EAAoB,OAASF,CAAI,GAM1D,YAAK,iBAAiB,WAAW,KAAK,CAAE,KAAAA,EAAM,MAAAD,CAAK,CAAE,EAGvD,KAAK,iBAAiB,WAAa,KAAK,iBAAiB,WAAW,OAClEG,GAAsB,CACpB,IAAMC,EAAc,IAAI,KAAKD,EAAoB,IAAI,EAAE,QAAO,EAE9D,OADY,KAAK,IAAG,EACPC,GAAeT,EAC9B,CAAC,EAEI,KAAK,SAAS,UAAU,KAAK,gBAAgB,EAUtD,MAAM,qBAAmB,CAKvB,GAJI,KAAK,mBAAqB,MAC5B,MAAM,KAAK,wBAIX,KAAK,mBAAqB,MAC1B,KAAK,iBAAiB,WAAW,SAAW,EAE5C,MAAO,GAET,IAAMM,EAAOC,GAAgB,EAEvB,CAAE,iBAAAG,EAAkB,cAAAC,CAAa,EAAKC,GAC1C,KAAK,iBAAiB,UAAU,EAE5BC,EAAeC,EACnB,KAAK,UAAU,CAAE,QAAS,EAAG,WAAYJ,CAAgB,CAAE,CAAC,EAG9D,YAAK,iBAAiB,sBAAwBJ,EAC1CK,EAAc,OAAS,GAEzB,KAAK,iBAAiB,WAAaA,EAInC,MAAM,KAAK,SAAS,UAAU,KAAK,gBAAgB,IAEnD,KAAK,iBAAiB,WAAa,CAAA,EAE9B,KAAK,SAAS,UAAU,KAAK,gBAAgB,GAE7CE,EAEV,EAED,SAASN,IAAgB,CAGvB,OAFc,IAAI,KAAI,EAET,YAAW,EAAG,UAAU,EAAG,EAAE,CAC5C,UAEgBK,GACdG,EACAC,EAAUjB,GAAgB,CAO1B,IAAMW,EAA4C,CAAA,EAE9CC,EAAgBI,EAAgB,MAAK,EACzC,QAAWP,KAAuBO,EAAiB,CAEjD,IAAME,EAAiBP,EAAiB,KACtCQ,GAAMA,EAAG,QAAUV,EAAoB,KAAK,EAE9C,GAAKS,GAgBH,GAHAA,EAAe,MAAM,KAAKT,EAAoB,IAAI,EAG9CW,GAAWT,CAAgB,EAAIM,EAAS,CAC1CC,EAAe,MAAM,IAAG,EACxB,KACD,UAjBDP,EAAiB,KAAK,CACpB,MAAOF,EAAoB,MAC3B,MAAO,CAACA,EAAoB,IAAI,CACjC,CAAA,EACGW,GAAWT,CAAgB,EAAIM,EAAS,CAG1CN,EAAiB,IAAG,EACpB,KACD,CAYHC,EAAgBA,EAAc,MAAM,CAAC,CACtC,CACD,MAAO,CACL,iBAAAD,EACA,cAAAC,EAEJ,KAEaR,QAAoB,CAE/B,YAAmBd,EAAgB,CAAhB,KAAG,IAAHA,EACjB,KAAK,wBAA0B,KAAK,6BAA4B,EAElE,MAAM,8BAA4B,CAChC,OAAK+B,EAAoB,EAGhBC,EAAyB,EAC7B,KAAK,IAAM,EAAI,EACf,MAAM,IAAM,EAAK,EAJb,GAUX,MAAM,MAAI,CAER,OADwB,MAAM,KAAK,wBAIN,MAAMjC,GAA4B,KAAK,GAAG,GACxC,CAAE,WAAY,CAAA,CAAE,EAHtC,CAAE,WAAY,CAAA,CAAE,EAO3B,MAAM,UAAUkC,EAAuC,OAErD,GADwB,MAAM,KAAK,wBAG5B,CACL,IAAMC,EAA2B,MAAM,KAAK,KAAI,EAChD,OAAO3B,GAA2B,KAAK,IAAK,CAC1C,uBACED,EAAA2B,EAAiB,yBACjB,MAAA3B,IAAA,OAAAA,EAAA4B,EAAyB,sBAC3B,WAAYD,EAAiB,UAC9B,CAAA,CACF,KATC,QAYJ,MAAM,IAAIA,EAAuC,OAE/C,GADwB,MAAM,KAAK,wBAG5B,CACL,IAAMC,EAA2B,MAAM,KAAK,KAAI,EAChD,OAAO3B,GAA2B,KAAK,IAAK,CAC1C,uBACED,EAAA2B,EAAiB,yBACjB,MAAA3B,IAAA,OAAAA,EAAA4B,EAAyB,sBAC3B,WAAY,CACV,GAAGA,EAAyB,WAC5B,GAAGD,EAAiB,UACrB,CACF,CAAA,CACF,KAZC,QAcL,EAOK,SAAUH,GAAWJ,EAAwC,CAEjE,OAAOD,EAEL,KAAK,UAAU,CAAE,QAAS,EAAG,WAAYC,CAAe,CAAE,CAAC,EAC3D,MACJ,CCvQM,SAAUS,GAAuBC,EAAgB,CACrDC,EACE,IAAIC,EACF,kBACAzB,GAAa,IAAI0B,GAA0B1B,CAAS,EAAC,SAAA,CAEtD,EAEHwB,EACE,IAAIC,EACF,YACAzB,GAAa,IAAID,GAAqBC,CAAS,EAAC,SAAA,CAEjD,EAIH2B,EAAgBC,GAAMC,GAASN,CAAO,EAEtCI,EAAgBC,GAAMC,GAAS,SAAkB,EAEjDF,EAAgB,UAAW,EAAE,CAC/B,CChBAL,GAAuB,EAAiB,gCCXxCQ,EAAgBC,GAAMC,GAAS,KAAK,+CCA7B,IAAMC,GAAqB,IAErBC,GAAkB,KAAKC,KACvBC,GAAwB,SAExBC,GACX,kDAEWC,GAA0B,GAAK,GAAK,IAEpCC,GAAU,gBACVC,GAAe,gBCD5B,IAAMC,GAAiE,CACrE,CAAA,6BACE,kDACF,CAAA,kBAA4B,2CAC5B,CAAA,0BAAoC,mCACpC,CAAA,kBACE,6FACF,CAAA,eAAyB,kDACzB,CAAA,+BACE,4EAaSC,EAAgB,IAAIC,EAC/BJ,GACAC,GACAC,EAAqB,EAYjB,SAAUG,GAAcC,EAAc,CAC1C,OACEA,aAAiBC,GACjBD,EAAM,KAAK,SAAQ,gBAAA,CAEvB,CCxCgB,SAAAE,GAAyB,CAAE,UAAAC,CAAS,EAAa,CAC/D,MAAO,GAAGX,eAAkCW,iBAC9C,CAEM,SAAUC,GACdC,EAAmC,CAEnC,MAAO,CACL,MAAOA,EAAS,MAChB,cAAsC,EACtC,UAAWC,GAAkCD,EAAS,SAAS,EAC/D,aAAc,KAAK,IAAG,EAE1B,CAEO,eAAeE,GACpBC,EACAH,EAAkB,CAGlB,IAAMI,GAD8B,MAAMJ,EAAS,KAAI,GACxB,MAC/B,OAAOR,EAAc,OAAiC,iBAAA,CACpD,YAAAW,EACA,WAAYC,EAAU,KACtB,cAAeA,EAAU,QACzB,aAAcA,EAAU,MACzB,CAAA,CACH,CAEgB,SAAAC,GAAW,CAAE,OAAAC,CAAM,EAAa,CAC9C,OAAO,IAAI,QAAQ,CACjB,eAAgB,mBAChB,OAAQ,mBACR,iBAAkBA,CACnB,CAAA,CACH,UAEgBC,GACdC,EACA,CAAE,aAAAC,CAAY,EAA+B,CAE7C,IAAMC,EAAUL,GAAWG,CAAS,EACpC,OAAAE,EAAQ,OAAO,gBAAiBC,GAAuBF,CAAY,CAAC,EAC7DC,CACT,CAeO,eAAeE,GACpBC,EAA2B,CAE3B,IAAMC,EAAS,MAAMD,EAAE,EAEvB,OAAIC,EAAO,QAAU,KAAOA,EAAO,OAAS,IAEnCD,EAAE,EAGJC,CACT,CAEA,SAASb,GAAkCc,EAAyB,CAElE,OAAO,OAAOA,EAAkB,QAAQ,IAAK,KAAK,CAAC,CACrD,CAEA,SAASJ,GAAuBF,EAAoB,CAClD,MAAO,GAAGvB,MAAyBuB,GACrC,CC7EO,eAAeO,GACpB,CAAE,UAAAR,EAAW,yBAAAS,CAAwB,EACrC,CAAE,IAAAC,CAAG,EAA+B,CAEpC,IAAMC,EAAWtB,GAAyBW,CAAS,EAE7CE,EAAUL,GAAWG,CAAS,EAG9BY,EAAmBH,EAAyB,aAAa,CAC7D,SAAU,EACX,CAAA,EACD,GAAIG,EAAkB,CACpB,IAAMC,EAAmB,MAAMD,EAAiB,oBAAmB,EAC/DC,GACFX,EAAQ,OAAO,oBAAqBW,CAAgB,CAEvD,CAED,IAAMC,EAAO,CACX,IAAAJ,EACA,YAAahC,GACb,MAAOsB,EAAU,MACjB,WAAYxB,IAGRuC,EAAuB,CAC3B,OAAQ,OACR,QAAAb,EACA,KAAM,KAAK,UAAUY,CAAI,GAGrBtB,EAAW,MAAMY,GAAmB,IAAM,MAAMO,EAAUI,CAAO,CAAC,EACxE,GAAIvB,EAAS,GAAI,CACf,IAAMwB,EAA4C,MAAMxB,EAAS,KAAI,EAOrE,MANiE,CAC/D,IAAKwB,EAAc,KAAON,EAC1B,mBAA2C,EAC3C,aAAcM,EAAc,aAC5B,UAAWzB,GAAiCyB,EAAc,SAAS,EAGtE,KACC,OAAM,MAAMtB,GAAqB,sBAAuBF,CAAQ,CAEpE,CC5DM,SAAUyB,GAAMC,EAAU,CAC9B,OAAO,IAAI,QAAcC,GAAU,CACjC,WAAWA,EAASD,CAAE,CACxB,CAAC,CACH,CCLM,SAAUE,GAAsBC,EAAiB,CAErD,OADY,KAAK,OAAO,aAAa,GAAGA,CAAK,CAAC,EACnC,QAAQ,MAAO,GAAG,EAAE,QAAQ,MAAO,GAAG,CACnD,CCDO,IAAMC,GAAoB,oBACpBC,GAAc,YAMXC,IAAW,CACzB,GAAI,CAGF,IAAMC,EAAe,IAAI,WAAW,EAAE,GAEpC,KAAK,QAAW,KAAyC,UACpD,gBAAgBA,CAAY,EAGnCA,EAAa,GAAK,IAAcA,EAAa,GAAK,GAElD,IAAMf,EAAMgB,GAAOD,CAAY,EAE/B,OAAOH,GAAkB,KAAKZ,CAAG,EAAIA,EAAMa,EAC5C,MAAC,CAEA,OAAOA,EACR,CACH,CAGA,SAASG,GAAOD,EAAwB,CAKtC,OAJkBL,GAAsBK,CAAY,EAInC,OAAO,EAAG,EAAE,CAC/B,CClCM,SAAUE,EAAO3B,EAAoB,CACzC,MAAO,GAAGA,EAAU,WAAWA,EAAU,OAC3C,CCDA,IAAM4B,GAA2D,IAAI,IAMrD,SAAAC,GAAW7B,EAAsBU,EAAW,CAC1D,IAAMoB,EAAMH,EAAO3B,CAAS,EAE5B+B,GAAuBD,EAAKpB,CAAG,EAC/BsB,GAAmBF,EAAKpB,CAAG,CAC7B,CAyCA,SAASuB,GAAuBC,EAAaC,EAAW,CACtD,IAAMC,EAAYC,GAAmB,IAAIH,CAAG,EAC5C,GAAI,EAACE,EAIL,QAAWE,KAAYF,EACrBE,EAASH,CAAG,CAEhB,CAEA,SAASI,GAAmBL,EAAaC,EAAW,CAClD,IAAMK,EAAUC,GAAmB,EAC/BD,GACFA,EAAQ,YAAY,CAAE,IAAAN,EAAK,IAAAC,CAAG,CAAE,EAElCO,GAAqB,CACvB,CAEA,IAAIC,EAA4C,KAEhD,SAASF,IAAmB,CAC1B,MAAI,CAACE,GAAoB,qBAAsB,OAC7CA,EAAmB,IAAI,iBAAiB,uBAAuB,EAC/DA,EAAiB,UAAY,GAAI,CAC/BV,GAAuB,EAAE,KAAK,IAAK,EAAE,KAAK,GAAG,CAC/C,GAEKU,CACT,CAEA,SAASD,IAAqB,CACxBL,GAAmB,OAAS,GAAKM,IACnCA,EAAiB,MAAK,EACtBA,EAAmB,KAEvB,CCtFA,IAAMC,GAAgB,kCAChBC,GAAmB,EACnBC,EAAoB,+BAStBC,GAA2D,KAC/D,SAASC,IAAY,CACnB,OAAKD,KACHA,GAAYE,EAAOL,GAAeC,GAAkB,CAClD,QAAS,CAACK,EAAIC,IAAc,CAM1B,OAAQA,EAAU,CAChB,IAAK,GACHD,EAAG,kBAAkBJ,CAAiB,CACzC,EAEJ,CAAA,GAEIC,EACT,CAeO,eAAeK,EACpBC,EACAC,EAAgB,CAEhB,IAAMpB,EAAMqB,EAAOF,CAAS,EAEtBG,GADK,MAAMR,GAAY,GACf,YAAYF,EAAmB,WAAW,EAClDW,EAAcD,EAAG,YAAYV,CAAiB,EAC9CY,EAAY,MAAMD,EAAY,IAAIvB,CAAG,EAC3C,aAAMuB,EAAY,IAAIH,EAAOpB,CAAG,EAChC,MAAMsB,EAAG,MAEL,CAACE,GAAYA,EAAS,MAAQJ,EAAM,MACtCK,GAAWN,EAAWC,EAAM,GAAG,EAG1BA,CACT,CAGO,eAAeM,GAAOP,EAAoB,CAC/C,IAAMnB,EAAMqB,EAAOF,CAAS,EAEtBG,GADK,MAAMR,GAAY,GACf,YAAYF,EAAmB,WAAW,EACxD,MAAMU,EAAG,YAAYV,CAAiB,EAAE,OAAOZ,CAAG,EAClD,MAAMsB,EAAG,IACX,CAQO,eAAeK,EACpBR,EACAS,EAAqE,CAErE,IAAM5B,EAAMqB,EAAOF,CAAS,EAEtBG,GADK,MAAMR,GAAY,GACf,YAAYF,EAAmB,WAAW,EAClDiB,EAAQP,EAAG,YAAYV,CAAiB,EACxCY,EAA2C,MAAMK,EAAM,IAC3D7B,CAAG,EAEC8B,EAAWF,EAASJ,CAAQ,EAElC,OAAIM,IAAa,OACf,MAAMD,EAAM,OAAO7B,CAAG,EAEtB,MAAM6B,EAAM,IAAIC,EAAU9B,CAAG,EAE/B,MAAMsB,EAAG,KAELQ,IAAa,CAACN,GAAYA,EAAS,MAAQM,EAAS,MACtDL,GAAWN,EAAWW,EAAS,GAAG,EAG7BA,CACT,CClFO,eAAeC,GACpBC,EAAwC,CAExC,IAAIC,EAEEC,EAAoB,MAAMP,EAAOK,EAAc,UAAWG,GAAW,CACzE,IAAMD,EAAoBE,GAAgCD,CAAQ,EAC5DE,EAAmBC,GACvBN,EACAE,CAAiB,EAEnB,OAAAD,EAAsBI,EAAiB,oBAChCA,EAAiB,iBAC1B,CAAC,EAED,OAAIH,EAAkB,MAAQK,GAErB,CAAE,kBAAmB,MAAMN,CAAoB,EAGjD,CACL,kBAAAC,EACA,oBAAAD,EAEJ,CAMA,SAASG,GACPD,EAAuC,CAEvC,IAAMK,EAA2BL,GAAY,CAC3C,IAAKM,GAAW,EAChB,mBAA6C,GAG/C,OAAOC,GAAqBF,CAAK,CACnC,CASA,SAASF,GACPN,EACAE,EAAoC,CAEpC,GAAIA,EAAkB,qBAAkB,EAAgC,CACtE,GAAI,CAAC,UAAU,OAAQ,CAErB,IAAMS,EAA+B,QAAQ,OAC3CC,EAAc,OAA6B,aAAA,CAAA,EAE7C,MAAO,CACL,kBAAAV,EACA,oBAAqBS,EAExB,CAGD,IAAME,EAA+C,CACnD,IAAKX,EAAkB,IACvB,mBAA6C,EAC7C,iBAAkB,KAAK,IAAG,GAEtBD,EAAsBa,GAC1Bd,EACAa,CAAe,EAEjB,MAAO,CAAE,kBAAmBA,EAAiB,oBAAAZ,CAAmB,CACjE,KAAM,QACLC,EAAkB,qBAAkB,EAE7B,CACL,kBAAAA,EACA,oBAAqBa,GAAyBf,CAAa,GAGtD,CAAE,kBAAAE,CAAiB,CAE9B,CAGA,eAAeY,GACbd,EACAE,EAA8C,CAE9C,GAAI,CACF,IAAMc,EAA8B,MAAMC,GACxCjB,EACAE,CAAiB,EAEnB,OAAOhB,EAAIc,EAAc,UAAWgB,CAA2B,CAChE,OAAQE,EAAP,CACA,MAAIC,GAAcD,CAAC,GAAKA,EAAE,WAAW,aAAe,IAGlD,MAAMxB,GAAOM,EAAc,SAAS,EAGpC,MAAMd,EAAIc,EAAc,UAAW,CACjC,IAAKE,EAAkB,IACvB,mBAA6C,CAC9C,CAAA,EAEGgB,CACP,CACH,CAGA,eAAeH,GACbf,EAAwC,CAMxC,IAAIQ,EAA2B,MAAMY,GACnCpB,EAAc,SAAS,EAEzB,KAAOQ,EAAM,qBAAkB,GAE7B,MAAMa,GAAM,GAAG,EAEfb,EAAQ,MAAMY,GAA0BpB,EAAc,SAAS,EAGjE,GAAIQ,EAAM,qBAAkB,EAAgC,CAE1D,GAAM,CAAE,kBAAAN,EAAmB,oBAAAD,CAAmB,EAC5C,MAAMF,GAAqBC,CAAa,EAE1C,OAAIC,GAIKC,CAEV,CAED,OAAOM,CACT,CAUA,SAASY,GACPjC,EAAoB,CAEpB,OAAOQ,EAAOR,EAAWgB,GAAW,CAClC,GAAI,CAACA,EACH,MAAMS,EAAc,OAAM,wBAAA,EAE5B,OAAOF,GAAqBP,CAAQ,CACtC,CAAC,CACH,CAEA,SAASO,GAAqBF,EAAwB,CACpD,OAAIc,GAA+Bd,CAAK,EAC/B,CACL,IAAKA,EAAM,IACX,mBAA6C,GAI1CA,CACT,CAEA,SAASc,GACPpB,EAAoC,CAEpC,OACEA,EAAkB,qBAAgD,GAClEA,EAAkB,iBAAmBqB,GAAqB,KAAK,IAAG,CAEtE,CClMO,eAAeC,GACpB,CAAE,UAAArC,EAAW,yBAAAsC,CAAwB,EACrCvB,EAA8C,CAE9C,IAAMwB,EAAWC,GAA6BxC,EAAWe,CAAiB,EAEpE0B,EAAUC,GAAmB1C,EAAWe,CAAiB,EAGzD4B,EAAmBL,EAAyB,aAAa,CAC7D,SAAU,EACX,CAAA,EACD,GAAIK,EAAkB,CACpB,IAAMC,EAAmB,MAAMD,EAAiB,oBAAmB,EAC/DC,GACFH,EAAQ,OAAO,oBAAqBG,CAAgB,CAEvD,CAED,IAAMC,EAAO,CACX,aAAc,CACZ,WAAYC,GACZ,MAAO9C,EAAU,KAClB,GAGG+C,EAAuB,CAC3B,OAAQ,OACR,QAAAN,EACA,KAAM,KAAK,UAAUI,CAAI,GAGrBG,EAAW,MAAMC,GAAmB,IAAM,MAAMV,EAAUQ,CAAO,CAAC,EACxE,GAAIC,EAAS,GAAI,CACf,IAAME,EAA2C,MAAMF,EAAS,KAAI,EAGpE,OADEG,GAAiCD,CAAa,CAEjD,KACC,OAAM,MAAME,GAAqB,sBAAuBJ,CAAQ,CAEpE,CAEA,SAASR,GACPxC,EACA,CAAE,IAAAlB,CAAG,EAA+B,CAEpC,MAAO,GAAGuE,GAAyBrD,CAAS,KAAKlB,uBACnD,CC1CO,eAAewE,GACpBzC,EACA0C,EAAe,GAAK,CAEpB,IAAIC,EACEnC,EAAQ,MAAMb,EAAOK,EAAc,UAAWG,GAAW,CAC7D,GAAI,CAACyC,GAAkBzC,CAAQ,EAC7B,MAAMS,EAAc,OAAM,gBAAA,EAG5B,IAAMiC,EAAe1C,EAAS,UAC9B,GAAI,CAACuC,GAAgBI,GAAiBD,CAAY,EAEhD,OAAO1C,EACF,GAAI0C,EAAa,gBAAa,EAEnC,OAAAF,EAAeI,GAA0B/C,EAAe0C,CAAY,EAC7DvC,EACF,CAEL,GAAI,CAAC,UAAU,OACb,MAAMS,EAAc,OAAM,aAAA,EAG5B,IAAMC,EAAkBmC,GAAoC7C,CAAQ,EACpE,OAAAwC,EAAeM,GAAyBjD,EAAea,CAAe,EAC/DA,CACR,CACH,CAAC,EAKD,OAHkB8B,EACd,MAAMA,EACLnC,EAAM,SAEb,CAQA,eAAeuC,GACb/C,EACA0C,EAAqB,CAMrB,IAAIlC,EAAQ,MAAM0C,GAAuBlD,EAAc,SAAS,EAChE,KAAOQ,EAAM,UAAU,gBAAa,GAElC,MAAMa,GAAM,GAAG,EAEfb,EAAQ,MAAM0C,GAAuBlD,EAAc,SAAS,EAG9D,IAAMmD,EAAY3C,EAAM,UACxB,OAAI2C,EAAU,gBAAa,EAElBV,GAAiBzC,EAAe0C,CAAY,EAE5CS,CAEX,CAUA,SAASD,GACP/D,EAAoB,CAEpB,OAAOQ,EAAOR,EAAWgB,GAAW,CAClC,GAAI,CAACyC,GAAkBzC,CAAQ,EAC7B,MAAMS,EAAc,OAAM,gBAAA,EAG5B,IAAMiC,EAAe1C,EAAS,UAC9B,OAAIiD,GAA4BP,CAAY,EAErC,OAAA,OAAA,OAAA,OAAA,CAAA,EAAA1C,CAAQ,EAAA,CACX,UAAW,CAAE,cAAa,CAAA,CAA6B,CACvD,EAGGA,CACT,CAAC,CACH,CAEA,eAAe8C,GACbjD,EACAE,EAA8C,CAE9C,GAAI,CACF,IAAMiD,EAAY,MAAM3B,GACtBxB,EACAE,CAAiB,EAEbmD,EACD,OAAA,OAAA,OAAA,OAAA,CAAA,EAAAnD,CAAiB,EACpB,CAAA,UAAAiD,CAAS,CAAA,EAEX,aAAMjE,EAAIc,EAAc,UAAWqD,CAAwB,EACpDF,CACR,OAAQjC,EAAP,CACA,GACEC,GAAcD,CAAC,IACdA,EAAE,WAAW,aAAe,KAAOA,EAAE,WAAW,aAAe,KAIhE,MAAMxB,GAAOM,EAAc,SAAS,MAC/B,CACL,IAAMqD,EACD,OAAA,OAAA,OAAA,OAAA,CAAA,EAAAnD,CAAiB,EACpB,CAAA,UAAW,CAAE,cAAa,CAAA,CAA6B,CAAA,EAEzD,MAAMhB,EAAIc,EAAc,UAAWqD,CAAwB,CAC5D,CACD,MAAMnC,CACP,CACH,CAEA,SAAS0B,GACP1C,EAAgD,CAEhD,OACEA,IAAsB,QACtBA,EAAkB,qBAA8C,CAEpE,CAEA,SAAS4C,GAAiBK,EAAoB,CAC5C,OACEA,EAAU,gBAAyC,GACnD,CAACG,GAAmBH,CAAS,CAEjC,CAEA,SAASG,GAAmBH,EAA6B,CACvD,IAAMI,EAAM,KAAK,IAAG,EACpB,OACEA,EAAMJ,EAAU,cAChBA,EAAU,aAAeA,EAAU,UAAYI,EAAMC,EAEzD,CAGA,SAASR,GACP7C,EAAqC,CAErC,IAAMsD,EAA2C,CAC/C,cAAwC,EACxC,YAAa,KAAK,IAAG,GAEvB,OAAA,OAAA,OAAA,OAAA,OAAA,CAAA,EACKtD,CAAQ,EAAA,CACX,UAAWsD,CAAmB,CAC9B,CACJ,CAEA,SAASL,GAA4BD,EAAoB,CACvD,OACEA,EAAU,gBAA2C,GACrDA,EAAU,YAAc5B,GAAqB,KAAK,IAAG,CAEzD,CCxLO,eAAemC,GAAM1D,EAA4B,CACtD,IAAM2D,EAAoB3D,EACpB,CAAE,kBAAAE,EAAmB,oBAAAD,CAAmB,EAAK,MAAMF,GACvD4D,CAAiB,EAGnB,OAAI1D,EACFA,EAAoB,MAAM,QAAQ,KAAK,EAIvCwC,GAAiBkB,CAAiB,EAAE,MAAM,QAAQ,KAAK,EAGlDzD,EAAkB,GAC3B,CCdO,eAAe0D,GACpB5D,EACA0C,EAAe,GAAK,CAEpB,IAAMiB,EAAoB3D,EAC1B,aAAM6D,GAAiCF,CAAiB,GAItC,MAAMlB,GAAiBkB,EAAmBjB,CAAY,GACvD,KACnB,CAEA,eAAemB,GACb7D,EAAwC,CAExC,GAAM,CAAE,oBAAAC,CAAmB,EAAK,MAAMF,GAAqBC,CAAa,EAEpEC,GAEF,MAAMA,CAEV,CK9BM,SAAU6D,GAAiBC,EAAgB,CAC/C,GAAI,CAACA,GAAO,CAACA,EAAI,QACf,MAAMC,GAAqB,mBAAmB,EAGhD,GAAI,CAACD,EAAI,KACP,MAAMC,GAAqB,UAAU,EAIvC,IAAMC,EAA2C,CAC/C,YACA,SACA,SAGF,QAAWC,KAAWD,EACpB,GAAI,CAACF,EAAI,QAAQG,GACf,MAAMF,GAAqBE,CAAO,EAItC,MAAO,CACL,QAASH,EAAI,KACb,UAAWA,EAAI,QAAQ,UACvB,OAAQA,EAAI,QAAQ,OACpB,MAAOA,EAAI,QAAQ,MAEvB,CAEA,SAASC,GAAqBG,EAAiB,CAC7C,OAAOC,EAAc,OAA4C,4BAAA,CAC/D,UAAAD,CACD,CAAA,CACH,CC3BA,IAAME,GAAqB,gBACrBC,GAA8B,yBAE9BC,GACJC,GACE,CACF,IAAMT,EAAMS,EAAU,YAAY,KAAK,EAAE,aAAY,EAE/CC,EAAYX,GAAiBC,CAAG,EAChCW,EAA2BC,EAAaZ,EAAK,WAAW,EAQ9D,MANqD,CACnD,IAAAA,EACA,UAAAU,EACA,yBAAAC,EACA,QAAS,IAAM,QAAQ,QAAO,EAGlC,EAEME,GACJJ,GACE,CACF,IAAMT,EAAMS,EAAU,YAAY,KAAK,EAAE,aAAY,EAE/CK,EAAgBF,EAAaZ,EAAKM,EAAkB,EAAE,aAAY,EAMxE,MAJ8D,CAC5D,MAAO,IAAMS,GAAMD,CAAa,EAChC,SAAWE,GAA2BC,GAASH,EAAeE,CAAY,EAG9E,WAEgBE,IAAqB,CACnCC,EACE,IAAIC,EAAUd,GAAoBE,GAAoC,QAAA,CAAA,EAExEW,EACE,IAAIC,EACFb,GACAM,GAED,SAAA,CAAA,CAEL,CC5CAK,GAAqB,EACrBG,EAAgBC,GAAMC,EAAO,EAE7BF,EAAgBC,GAAMC,GAAS,SAAkB,ECb1C,IAAMC,GACX,0FAEWC,GAAW,6CAGXC,GAAU,UAEVC,GAAsB,kBAgBtBC,GAAmB,EACnBC,GAA0B,EAE3BC,GAAZ,SAAYA,EAAW,CACrBA,EAAAA,EAAA,aAAA,GAAA,eACAA,EAAAA,EAAA,qBAAA,GAAA,sBACF,GAHYA,IAAAA,EAGX,CAAA,EAAA,ECGD,IAAYA,GAAZ,SAAYA,EAAW,CACrBA,EAAA,cAAA,gBACAA,EAAA,qBAAA,sBACF,GAHYA,IAAAA,EAGX,CAAA,EAAA,ECvCK,SAAUC,EAAcC,EAA+B,CAC3D,IAAMC,EAAa,IAAI,WAAWD,CAAK,EAEvC,OADqB,KAAK,OAAO,aAAa,GAAGC,CAAU,CAAC,EACxC,QAAQ,KAAM,EAAE,EAAE,QAAQ,MAAO,GAAG,EAAE,QAAQ,MAAO,GAAG,CAC9E,CAEM,SAAUC,GAAcC,EAAoB,CAChD,IAAMC,EAAU,IAAI,QAAQ,EAAKD,EAAa,OAAS,GAAM,CAAC,EACxDE,GAAUF,EAAeC,GAC5B,QAAQ,MAAO,GAAG,EAClB,QAAQ,KAAM,GAAG,EAEdE,EAAU,KAAKD,CAAM,EACrBE,EAAc,IAAI,WAAWD,EAAQ,MAAM,EAEjD,QAASE,EAAI,EAAGA,EAAIF,EAAQ,OAAQ,EAAEE,EACpCD,EAAYC,GAAKF,EAAQ,WAAWE,CAAC,EAEvC,OAAOD,CACT,CCyBA,IAAME,GAAc,uBAKdC,GAAiB,EACjBC,GAAwB,yBAEvB,eAAeC,GACpBC,EAAgB,CAEhB,GAAI,cAAe,WAUb,EAPc,MAChB,UAGA,UAAS,GACe,IAAIC,GAAMA,EAAG,IAAI,EAE9B,SAASL,EAAW,EAE/B,OAAO,KAIX,IAAIM,EAAoC,KA2ExC,OAzEW,MAAMC,EAAOP,GAAaC,GAAgB,CACnD,QAAS,MAAOI,EAAIG,EAAYC,EAAYC,IAAsB,OAMhE,GALIF,EAAa,GAKb,CAACH,EAAG,iBAAiB,SAASH,EAAqB,EAErD,OAGF,IAAMS,EAAcD,EAAmB,YAAYR,EAAqB,EAClEU,EAAQ,MAAMD,EAAY,MAAM,aAAa,EAAE,IAAIP,CAAQ,EAGjE,GAFA,MAAMO,EAAY,MAAK,EAEnB,EAACC,GAKL,GAAIJ,IAAe,EAAG,CACpB,IAAMK,EAAaD,EAEnB,GAAI,CAACC,EAAW,MAAQ,CAACA,EAAW,QAAU,CAACA,EAAW,SACxD,OAGFP,EAAe,CACb,MAAOO,EAAW,SAClB,YAAYC,EAAAD,EAAW,cAAc,MAAAC,IAAA,OAAAA,EAAA,KAAK,IAAG,EAC7C,oBAAqB,CACnB,KAAMD,EAAW,KACjB,OAAQA,EAAW,OACnB,SAAUA,EAAW,SACrB,QAASA,EAAW,QACpB,SACE,OAAOA,EAAW,UAAa,SAC3BA,EAAW,SACXvB,EAAcuB,EAAW,QAAQ,CACxC,EAEJ,SAAUL,IAAe,EAAG,CAC3B,IAAMK,EAAaD,EAEnBN,EAAe,CACb,MAAOO,EAAW,SAClB,WAAYA,EAAW,WACvB,oBAAqB,CACnB,KAAMvB,EAAcuB,EAAW,IAAI,EACnC,OAAQvB,EAAcuB,EAAW,MAAM,EACvC,SAAUA,EAAW,SACrB,QAASA,EAAW,QACpB,SAAUvB,EAAcuB,EAAW,QAAQ,CAC5C,EAEJ,SAAUL,IAAe,EAAG,CAC3B,IAAMK,EAAaD,EAEnBN,EAAe,CACb,MAAOO,EAAW,SAClB,WAAYA,EAAW,WACvB,oBAAqB,CACnB,KAAMvB,EAAcuB,EAAW,IAAI,EACnC,OAAQvB,EAAcuB,EAAW,MAAM,EACvC,SAAUA,EAAW,SACrB,QAASA,EAAW,QACpB,SAAUvB,EAAcuB,EAAW,QAAQ,CAC5C,EAEJ,GAEJ,CAAA,GACE,MAAK,EAGR,MAAME,EAASf,EAAW,EAC1B,MAAMe,EAAS,sBAAsB,EACrC,MAAMA,EAAS,WAAW,EAEnBC,GAAkBV,CAAY,EAAIA,EAAe,IAC1D,CAEA,SAASU,GACPV,EAAiC,CAEjC,GAAI,CAACA,GAAgB,CAACA,EAAa,oBACjC,MAAO,GAET,GAAM,CAAE,oBAAAW,CAAmB,EAAKX,EAChC,OACE,OAAOA,EAAa,YAAe,UACnCA,EAAa,WAAa,GAC1B,OAAOA,EAAa,OAAU,UAC9BA,EAAa,MAAM,OAAS,GAC5B,OAAOW,EAAoB,MAAS,UACpCA,EAAoB,KAAK,OAAS,GAClC,OAAOA,EAAoB,QAAW,UACtCA,EAAoB,OAAO,OAAS,GACpC,OAAOA,EAAoB,UAAa,UACxCA,EAAoB,SAAS,OAAS,GACtC,OAAOA,EAAoB,SAAY,UACvCA,EAAoB,QAAQ,OAAS,GACrC,OAAOA,EAAoB,UAAa,UACxCA,EAAoB,SAAS,OAAS,CAE1C,CC5KO,IAAMC,GAAgB,8BACvBC,GAAmB,EACnBC,EAAoB,2BAStBC,GAAuD,KAC3D,SAASC,IAAY,CACnB,OAAKD,KACHA,GAAYd,EAAOW,GAAeC,GAAkB,CAClD,QAAS,CAACI,EAAWf,IAAc,CAKjC,OAAQA,EAAU,CAChB,IAAK,GACHe,EAAU,kBAAkBH,CAAiB,CAChD,EAEJ,CAAA,GAEIC,EACT,CAGO,eAAeG,GACpBC,EAAkD,CAElD,IAAMC,EAAMC,GAAOF,CAAoB,EAEjCnB,EAAgB,MADX,MAAMgB,GAAY,GAE1B,YAAYF,CAAiB,EAC7B,YAAYA,CAAiB,EAC7B,IAAIM,CAAG,EAEV,GAAIpB,EACF,OAAOA,EACF,CAEL,IAAMsB,EAAkB,MAAMzB,GAC5BsB,EAAqB,UAAU,QAAQ,EAEzC,GAAIG,EACF,aAAMC,GAAMJ,EAAsBG,CAAe,EAC1CA,CAEV,CACH,CAGO,eAAeC,GACpBJ,EACAnB,EAA0B,CAE1B,IAAMoB,EAAMC,GAAOF,CAAoB,EAEjCK,GADK,MAAMR,GAAY,GACf,YAAYF,EAAmB,WAAW,EACxD,aAAMU,EAAG,YAAYV,CAAiB,EAAE,IAAId,EAAcoB,CAAG,EAC7D,MAAMI,EAAG,KACFxB,CACT,CAGO,eAAeyB,GACpBN,EAAkD,CAElD,IAAMC,EAAMC,GAAOF,CAAoB,EAEjCK,GADK,MAAMR,GAAY,GACf,YAAYF,EAAmB,WAAW,EACxD,MAAMU,EAAG,YAAYV,CAAiB,EAAE,OAAOM,CAAG,EAClD,MAAMI,EAAG,IACX,CAWA,SAASH,GAAO,CAAE,UAAAK,CAAS,EAAgC,CACzD,OAAOA,EAAU,KACnB,CC1EO,IAAMC,GAAiC,CAC5C,CAAA,6BACE,kDACF,CAAA,4BACE,gDACF,CAAA,wBACE,wDACF,CAAA,sBACE,qEACF,CAAA,sBACE,mEACF,CAAA,uBACE,2EACF,CAAA,0BACE,mGACF,CAAA,sCACE,+EACF,CAAA,0BACE,qEACF,CAAA,4BACE,2DACF,CAAA,4BACE,yEAEF,CAAA,uBACE,oEACF,CAAA,yBACE,wDACF,CAAA,0BACE,4IAEF,CAAA,2BACE,uEACF,CAAA,sBACE,iEACF,CAAA,qBAA+B,yCAC/B,CAAA,iCACE,yIAcSC,EAAgB,IAAIC,EAC/B,YACA,YACAF,EAAS,ECxDJ,eAAeG,GACpBX,EACAR,EAAwC,OAExC,IAAMoB,EAAU,MAAMC,GAAWb,CAAoB,EAC/Cc,EAAOC,GAAQvB,CAAmB,EAElCwB,EAAmB,CACvB,OAAQ,OACR,QAAAJ,EACA,KAAM,KAAK,UAAUE,CAAI,GAGvBG,EACJ,GAAI,CAKFA,EAAe,MAJE,MAAM,MACrBC,GAAYlB,EAAqB,SAAS,EAC1CgB,CAAgB,GAEY,KAAI,CACnC,OAAQG,EAAP,CACA,MAAMV,EAAc,OAAyC,yBAAA,CAC3D,WAAWpB,EAAC8B,KAAa,MAAA9B,IAAA,OAAA,OAAAA,EAAE,SAAQ,CACpC,CAAA,CACF,CAED,GAAI4B,EAAa,MAAO,CACtB,IAAMG,EAAUH,EAAa,MAAM,QACnC,MAAMR,EAAc,OAAyC,yBAAA,CAC3D,UAAWW,CACZ,CAAA,CACF,CAED,GAAI,CAACH,EAAa,MAChB,MAAMR,EAAc,OAAM,0BAAA,EAG5B,OAAOQ,EAAa,KACtB,CAEO,eAAeI,GACpBrB,EACAnB,EAA0B,OAE1B,IAAM+B,EAAU,MAAMC,GAAWb,CAAoB,EAC/Cc,EAAOC,GAAQlC,EAAa,mBAAoB,EAEhDyC,EAAgB,CACpB,OAAQ,QACR,QAAAV,EACA,KAAM,KAAK,UAAUE,CAAI,GAGvBG,EACJ,GAAI,CAKFA,EAAe,MAJE,MAAM,MACrB,GAAGC,GAAYlB,EAAqB,SAAS,KAAKnB,EAAa,QAC/DyC,CAAa,GAEe,KAAI,CACnC,OAAQH,EAAP,CACA,MAAMV,EAAc,OAAsC,sBAAA,CACxD,WAAWpB,EAAC8B,KAAa,MAAA9B,IAAA,OAAA,OAAAA,EAAE,SAAQ,CACpC,CAAA,CACF,CAED,GAAI4B,EAAa,MAAO,CACtB,IAAMG,EAAUH,EAAa,MAAM,QACnC,MAAMR,EAAc,OAAsC,sBAAA,CACxD,UAAWW,CACZ,CAAA,CACF,CAED,GAAI,CAACH,EAAa,MAChB,MAAMR,EAAc,OAAM,uBAAA,EAG5B,OAAOQ,EAAa,KACtB,CAEO,eAAeM,GACpBvB,EACAwB,EAAa,OAEb,IAAMZ,EAAU,MAAMC,GAAWb,CAAoB,EAE/CyB,EAAqB,CACzB,OAAQ,SACR,QAAAb,GAGF,GAAI,CAKF,IAAMK,EAA4B,MAJjB,MAAM,MACrB,GAAGC,GAAYlB,EAAqB,SAAS,KAAKwB,IAClDC,CAAkB,GAE6B,KAAI,EACrD,GAAIR,EAAa,MAAO,CACtB,IAAMG,EAAUH,EAAa,MAAM,QACnC,MAAMR,EAAc,OAA2C,2BAAA,CAC7D,UAAWW,CACZ,CAAA,CACF,CACF,OAAQD,EAAP,CACA,MAAMV,EAAc,OAA2C,2BAAA,CAC7D,WAAWpB,EAAC8B,KAAa,MAAA9B,IAAA,OAAA,OAAAA,EAAE,SAAQ,CACpC,CAAA,CACF,CACH,CAEA,SAAS6B,GAAY,CAAE,UAAAQ,CAAS,EAAa,CAC3C,MAAO,GAAGnE,eAAqBmE,iBACjC,CAEA,eAAeb,GAAW,CACxB,UAAAN,EACA,cAAAoB,CAAa,EACgB,CAC7B,IAAMC,EAAY,MAAMD,EAAc,SAAQ,EAE9C,OAAO,IAAI,QAAQ,CACjB,eAAgB,mBAChB,OAAQ,mBACR,iBAAkBpB,EAAU,OAC5B,qCAAsC,OAAOqB,GAC9C,CAAA,CACH,CAEA,SAASb,GAAQ,CACf,OAAAc,EACA,KAAAC,EACA,SAAAC,EACA,SAAAC,CAAQ,EACY,CACpB,IAAMlB,EAAuB,CAC3B,IAAK,CACH,SAAAiB,EACA,KAAAD,EACA,OAAAD,CACD,GAGH,OAAIG,IAAa1E,KACfwD,EAAK,IAAI,kBAAoBkB,GAGxBlB,CACT,CCxJA,IAAMmB,GAAsB,EAAI,GAAK,GAAK,GAAK,IAExC,eAAeC,GACpBC,EAA2B,CAE3B,IAAMC,EAAmB,MAAMC,GAC7BF,EAAU,eACVA,EAAU,QAAS,EAGf3C,EAA2C,CAC/C,SAAU2C,EAAU,SACpB,QAASA,EAAU,eAAgB,MACnC,SAAUC,EAAiB,SAC3B,KAAMvE,EAAcuE,EAAiB,OAAO,MAAM,CAAE,EACpD,OAAQvE,EAAcuE,EAAiB,OAAO,QAAQ,CAAE,GAGpDvD,EAAe,MAAMkB,GAAMoC,EAAU,oBAAoB,EAC/D,GAAKtD,EAGE,IACJyD,GAAazD,EAAa,oBAAsBW,CAAmB,EAc/D,OAAI,KAAK,IAAG,GAAMX,EAAa,WAAaoD,GAE1CM,GAAYJ,EAAW,CAC5B,MAAOtD,EAAa,MACpB,WAAY,KAAK,IAAG,EACpB,oBAAAW,CACD,CAAA,EAGMX,EAAa,MApBpB,GAAI,CACF,MAAM0C,GACJY,EAAU,qBACVtD,EAAa,KAAK,CAErB,OAAQ2D,EAAP,CAEA,QAAQ,KAAKA,CAAC,CACf,CAED,OAAOC,GAAYN,EAAU,qBAAuB3C,CAAmB,MAfvE,QAAOiD,GAAYN,EAAU,qBAAsB3C,CAAmB,CA2B1E,CAMO,eAAekD,GACpBP,EAA2B,CAE3B,IAAMtD,EAAe,MAAMkB,GAAMoC,EAAU,oBAAoB,EAC3DtD,IACF,MAAM0C,GACJY,EAAU,qBACVtD,EAAa,KAAK,EAEpB,MAAMyB,GAAS6B,EAAU,oBAAoB,GAI/C,IAAMC,EACJ,MAAMD,EAAU,eAAgB,YAAY,gBAAe,EAC7D,OAAIC,EACKA,EAAiB,YAAW,EAI9B,EACT,CAEA,eAAeG,GACbJ,EACAtD,EAA0B,CAE1B,GAAI,CACF,IAAM8D,EAAe,MAAMtB,GACzBc,EAAU,qBACVtD,CAAY,EAGR+D,EAAmB,OAAA,OAAA,OAAA,OAAA,CAAA,EACpB/D,CAAY,EAAA,CACf,MAAO8D,EACP,WAAY,KAAK,IAAG,CAAE,CAAA,EAGxB,aAAMvC,GAAM+B,EAAU,qBAAsBS,CAAmB,EACxDD,CACR,OAAQH,EAAP,CACA,YAAME,GAAoBP,CAAS,EAC7BK,CACP,CACH,CAEA,eAAeC,GACbzC,EACAR,EAAwC,CAMxC,IAAMX,EAA6B,CACjC,MALY,MAAM8B,GAClBX,EACAR,CAAmB,EAInB,WAAY,KAAK,IAAG,EACpB,oBAAAA,GAEF,aAAMY,GAAMJ,EAAsBnB,CAAY,EACvCA,EAAa,KACtB,CAKA,eAAewD,GACbQ,EACAb,EAAgB,CAEhB,IAAMc,EAAe,MAAMD,EAAe,YAAY,gBAAe,EACrE,OAAIC,GAIGD,EAAe,YAAY,UAAU,CAC1C,gBAAiB,GAGjB,qBAAsB7E,GAAcgE,CAAQ,CAC7C,CAAA,CACH,CAKA,SAASM,GACPS,EACAC,EAAmC,CAEnC,IAAMC,EAAkBD,EAAe,WAAaD,EAAU,SACxDG,EAAkBF,EAAe,WAAaD,EAAU,SACxDI,EAAcH,EAAe,OAASD,EAAU,KAChDK,EAAgBJ,EAAe,SAAWD,EAAU,OAE1D,OAAOE,GAAmBC,GAAmBC,GAAeC,CAC9D,CCpKM,SAAUC,GACdC,EAAuC,CAEvC,IAAMC,EAA0B,CAC9B,KAAMD,EAAgB,KAEtB,YAAaA,EAAgB,aAE7B,UAAWA,EAAgB,cAG7B,OAAAE,GAA6BD,EAASD,CAAe,EACrDG,GAAqBF,EAASD,CAAe,EAC7CI,GAAoBH,EAASD,CAAe,EAErCC,CACT,CAEA,SAASC,GACPD,EACAI,EAA8C,CAE9C,GAAI,CAACA,EAAuB,aAC1B,OAGFJ,EAAQ,aAAe,CAAA,EAEvB,IAAMK,EAAQD,EAAuB,aAAc,MAC7CC,IACJL,EAAQ,aAAc,MAAQK,GAGhC,IAAM9C,EAAO6C,EAAuB,aAAc,KAC5C7C,IACJyC,EAAQ,aAAc,KAAOzC,GAG/B,IAAM+C,EAAQF,EAAuB,aAAc,MAC7CE,IACJN,EAAQ,aAAc,MAAQM,EAElC,CAEA,SAASJ,GACPF,EACAI,EAA8C,CAE1C,CAACA,EAAuB,OAI5BJ,EAAQ,KAAOI,EAAuB,KACxC,CAEA,SAASD,GACPH,EACAI,EAA8C,eAG9C,GACE,CAACA,EAAuB,YACxB,EAAC,GAAAtE,EAAAsE,EAAuB,gBAAc,MAAAtE,IAAA,SAAAA,EAAA,cAEtC,OAGFkE,EAAQ,WAAa,CAAA,EAErB,IAAMO,GACJC,GAAAC,EAAAL,EAAuB,cAAU,MAAAK,IAAA,OAAA,OAAAA,EAAE,QAAI,MAAAD,IAAA,OAAAA,GACvCE,EAAAN,EAAuB,gBAAY,MAAAM,IAAA,OAAA,OAAAA,EAAE,aAEjCH,IACJP,EAAQ,WAAY,KAAOO,GAI7B,IAAMI,GAAiBC,EAAAR,EAAuB,cAAU,MAAAQ,IAAA,OAAA,OAAAA,EAAE,gBACpDD,IACJX,EAAQ,WAAY,eAAiBW,EAEzC,CClFM,SAAUE,GAAiBC,EAAa,CAE5C,OAAO,OAAOA,GAAS,UAAY,CAAC,CAACA,GAAQ5G,MAAuB4G,CACtE,CCLM,SAAUC,GAAMC,EAAU,CAC9B,OAAO,IAAI,QAAcC,GAAU,CACjC,WAAWA,EAASD,CAAE,CACxB,CAAC,CACH,CCeyBE,GACvB,mCACA,iCAAiC,EAGTA,GACxB,uBACA,qBAAqB,EA+GhB,eAAeC,GACpBvC,EACAmB,EAAuC,CAEvC,IAAMqB,EAAWC,GACftB,EACA,MAAMnB,EAAU,qBAAqB,cAAc,MAAK,CAAE,EAG5D0C,GAAyB1C,EAAWwC,CAAQ,CAC9C,CAEA,SAASC,GACPtB,EACAwB,EAAW,SAEX,IAAMH,EAAW,CAAA,EAIjB,OAAMrB,EAAgB,OACpBqB,EAAS,eAAiBrB,EAAgB,MAGtCA,EAAgB,eACpBqB,EAAS,WAAarB,EAAgB,cAGxCqB,EAAS,YAAcG,EAEjBxB,EAAgB,aACpBqB,EAAS,aAAe/G,EAAY,qBAAqB,SAAQ,EAEjE+G,EAAS,aAAe/G,EAAY,aAAa,SAAQ,EAG3D+G,EAAS,aAAejH,GAAiB,SAAQ,EACjDiH,EAAS,aAAe,KAAK,OAAO,QAAQ,gBAAiB,EAAE,EAEzDrB,EAAgB,eACpBqB,EAAS,aAAerB,EAAgB,cAG1CqB,EAAS,MAAQhH,GAAwB,SAAQ,EAE3C,GAAA0B,EAAAiE,EAAgB,cAAU,MAAAjE,IAAA,SAAAA,EAAE,kBAChCsF,EAAS,iBAAkBX,EAAAV,EAAgB,cAAY,MAAAU,IAAA,OAAA,OAAAA,EAAA,iBAIlDW,CACT,CAEA,SAASE,GACP1C,EACAwC,EAAkB,CAElB,IAAMI,EAAW,CAAA,EAGjBA,EAAS,cAAgB,KAAK,MAAM,KAAK,IAAG,CAAE,EAAE,SAAQ,EACxDA,EAAS,6BAA+B,KAAK,UAAUJ,CAAQ,EAG/DxC,EAAU,UAAU,KAAK4C,CAAQ,CACnC,CAagB,SAAAN,GAAcO,EAAYC,EAAU,CAClD,IAAMC,EAAc,CAAA,EACpB,QAAS5G,EAAI,EAAGA,EAAI0G,EAAG,OAAQ1G,IAC7B4G,EAAY,KAAKF,EAAG,OAAO1G,CAAC,CAAC,EACzBA,EAAI2G,EAAG,QACTC,EAAY,KAAKD,EAAG,OAAO3G,CAAC,CAAC,EAIjC,OAAO4G,EAAY,KAAK,EAAE,CAC5B,CCtMO,eAAeC,GACpBC,EACAjD,EAA2B,SAE3B,GAAM,CAAE,gBAAAkD,CAAe,EAAKD,EAC5B,GAAI,CAACC,EAAiB,CAEpB,MAAM3C,GAAoBP,CAAS,EACnC,MACD,CAED,IAAMtD,EAAe,MAAMkB,GAAMoC,EAAU,oBAAoB,EAC/D,MAAMO,GAAoBP,CAAS,EAEnCA,EAAU,UACR6B,GAAA3E,EAAAR,GAAc,uBAAqB,MAAAQ,IAAA,OAAA,OAAAA,EAAA,YAAY,MAAA2E,IAAA,OAAAA,EAAA1G,GACjD,MAAM4E,GAAiBC,CAAS,CAClC,CAEO,eAAemD,GACpBF,EACAjD,EAA2B,CAE3B,IAAMmB,EAAkBiC,GAA0BH,CAAK,EACvD,GAAI,CAAC9B,EAEH,OAIEnB,EAAU,0CACZ,MAAMuC,GAASvC,EAAWmB,CAAe,EAI3C,IAAMkC,EAAa,MAAMC,GAAa,EACtC,GAAIC,GAAkBF,CAAU,EAC9B,OAAOG,GAAoCH,EAAYlC,CAAe,EAQxE,GAJMA,EAAgB,cACpB,MAAMsC,GAAiBC,GAAoBvC,CAAe,CAAC,EAGzD,EAACnB,GAICA,EAAU,2BAA4B,CAC1C,IAAMoB,EAAUF,GAAmBC,CAAe,EAE9C,OAAOnB,EAAU,4BAA+B,WAClD,MAAMA,EAAU,2BAA2BoB,CAAO,EAElDpB,EAAU,2BAA2B,KAAKoB,CAAO,CAEpD,CACH,CAEO,eAAeuC,GACpBV,EAAwB,SAExB,IAAM9B,GACJU,GAAA3E,EAAA+F,EAAM,gBAAY,MAAA/F,IAAA,OAAA,OAAAA,EAAE,QAAI,MAAA2E,IAAA,OAAA,OAAAA,EAAGxG,IAE7B,GAAK8F,GAEE,GAAI8B,EAAM,OAGf,WAJA,QAQFA,EAAM,yBAAwB,EAC9BA,EAAM,aAAa,MAAK,EAGxB,IAAMtB,EAAOiC,GAAQzC,CAAe,EACpC,GAAI,CAACQ,EACH,OAIF,IAAMkC,EAAM,IAAI,IAAIlC,EAAM,KAAK,SAAS,IAAI,EACtCmC,EAAY,IAAI,IAAI,KAAK,SAAS,MAAM,EAE9C,GAAID,EAAI,OAASC,EAAU,KACzB,OAGF,IAAIC,EAAS,MAAMC,GAAgBH,CAAG,EAYtC,GAVKE,EAOHA,EAAS,MAAMA,EAAO,MAAK,GAN3BA,EAAS,MAAM,KAAK,QAAQ,WAAWpC,CAAI,EAI3C,MAAMQ,GAAM,GAAI,GAKd,EAAC4B,EAKL,OAAA5C,EAAgB,YAAc1F,EAAY,qBAC1C0F,EAAgB,oBAAsB,GAC/B4C,EAAO,YAAY5C,CAAe,CAC3C,CAEA,SAASuC,GACPvC,EAAuC,CAEvC,IAAM8C,EACA,OAAA,OAAA,CAAA,EAAA9C,EAAgB,YAAuD,EAM7E,OAAA8C,EAAuB,KAAO,CAC5B,CAAC5I,IAAU8F,GAGN8C,CACT,CAEA,SAASb,GAA0B,CACjC,KAAAlB,CAAI,EACM,CACV,GAAI,CAACA,EACH,OAAO,KAGT,GAAI,CACF,OAAOA,EAAK,KAAI,CACjB,MAAC,CAEA,OAAO,IACR,CACH,CAMA,eAAe8B,GAAgBH,EAAQ,CACrC,IAAMR,EAAa,MAAMC,GAAa,EAEtC,QAAWS,KAAUV,EAAY,CAC/B,IAAMa,EAAY,IAAI,IAAIH,EAAO,IAAK,KAAK,SAAS,IAAI,EAExD,GAAIF,EAAI,OAASK,EAAU,KACzB,OAAOH,CAEV,CAED,OAAO,IACT,CAMA,SAASR,GAAkBF,EAA0B,CACnD,OAAOA,EAAW,KAChBU,GACEA,EAAO,kBAAoB,WAG3B,CAACA,EAAO,IAAI,WAAW,qBAAqB,CAAC,CAEnD,CAEA,SAASP,GACPH,EACAlC,EAAuC,CAEvCA,EAAgB,oBAAsB,GACtCA,EAAgB,YAAc1F,EAAY,cAE1C,QAAWsI,KAAUV,EACnBU,EAAO,YAAY5C,CAAe,CAEtC,CAEA,SAASmC,IAAa,CACpB,OAAO,KAAK,QAAQ,SAAS,CAC3B,KAAM,SACN,oBAAqB,EAEtB,CAAA,CACH,CAEA,SAASG,GACPU,EAAwD,OAIxD,GAAM,CAAE,QAAAC,CAAO,EAAKD,EACd,CAAE,WAAAE,CAAU,EAAK,aACvB,OAAID,GAAWC,GAAcD,EAAQ,OAASC,GAC5C,QAAQ,KACN,8BAA8BA,yDAAkE,EAI7F,KAAK,aAAa,kBACVnH,EAAAiH,EAA4B,SAAK,MAAAjH,IAAA,OAAAA,EAAI,GAClDiH,CAA2B,CAE/B,CAEA,SAASP,GAAQxC,EAA+B,WAE9C,IAAMO,GAAOE,GAAA3E,EAAAkE,EAAQ,cAAU,MAAAlE,IAAA,OAAA,OAAAA,EAAE,QAAI,MAAA2E,IAAA,OAAAA,GAAID,EAAAR,EAAQ,gBAAY,MAAAQ,IAAA,OAAA,OAAAA,EAAE,aAC/D,OAAID,IAIAM,GAAiBb,EAAQ,IAAI,EAExB,KAAK,SAAS,OAEd,KAEX,CC5PM,SAAUkD,GAAiBC,EAAgB,CAC/C,GAAI,CAACA,GAAO,CAACA,EAAI,QACf,MAAMC,GAAqB,0BAA0B,EAGvD,GAAI,CAACD,EAAI,KACP,MAAMC,GAAqB,UAAU,EAIvC,IAAMC,EAAmD,CACvD,YACA,SACA,QACA,qBAGI,CAAE,QAAAC,CAAO,EAAKH,EACpB,QAAWI,KAAWF,EACpB,GAAI,CAACC,EAAQC,GACX,MAAMH,GAAqBG,CAAO,EAItC,MAAO,CACL,QAASJ,EAAI,KACb,UAAWG,EAAQ,UACnB,OAAQA,EAAQ,OAChB,MAAOA,EAAQ,MACf,SAAUA,EAAQ,kBAEtB,CAEA,SAASF,GAAqBI,EAAiB,CAC7C,OAAOtG,EAAc,OAA4C,4BAAA,CAC/D,UAAAsG,CACD,CAAA,CACH,KCjCaC,QAAgB,CAoB3B,YACEN,EACA/E,EACAsF,EAA0D,CAhB5D,KAAwC,yCAAY,GAEpD,KAA0B,2BAGf,KAEX,KAAgB,iBACd,KAEF,KAAS,UAAe,CAAA,EACxB,KAAmB,oBAAY,GAO7B,IAAM1G,EAAYkG,GAAiBC,CAAG,EAEtC,KAAK,qBAAuB,CAC1B,IAAAA,EACA,UAAAnG,EACA,cAAAoB,EACA,kBAAAsF,GAIJ,SAAO,CACL,OAAO,QAAQ,QAAO,EAEzB,ECKD,IAAMC,GACJC,GACE,CACF,IAAMhF,EAAY,IAAI6E,GACpBG,EAAU,YAAY,KAAK,EAAE,aAAY,EACzCA,EAAU,YAAY,wBAAwB,EAAE,aAAY,EAC5DA,EAAU,YAAY,oBAAoB,CAAC,EAG7C,YAAK,iBAAiB,OAAQ3E,GAAI,CAChCA,EAAE,UAAU8C,GAAO9C,EAAGL,CAA6B,CAAC,CACtD,CAAC,EACD,KAAK,iBAAiB,yBAA0BK,GAAI,CAClDA,EAAE,UAAU2C,GAAY3C,EAAGL,CAA6B,CAAC,CAC3D,CAAC,EACD,KAAK,iBAAiB,oBAAqBK,GAAI,CAC7CA,EAAE,UAAUsD,GAAoBtD,CAAC,CAAC,CACpC,CAAC,EAEML,CACT,WAyBgBiF,IAAqB,CACnCC,EACE,IAAIC,EAAU,eAAgBJ,GAAyC,QAAA,CAAA,CAE3E,CC5DO,eAAeK,IAAa,CAIjC,OACEC,EAAoB,GACnB,MAAMC,EAAyB,GAChC,gBAAiB,MACjB,iBAAkB,MAClB,0BAA0B,UAAU,eAAe,kBAAkB,GACrE,iBAAiB,UAAU,eAAe,QAAQ,CAEtD,CC5CgB,SAAAC,GACdvF,EACAwF,EAAiE,CAEjE,GAAI,KAAK,WAAa,OACpB,MAAMlH,EAAc,OAAM,sBAAA,EAG5B,OAAA0B,EAAU,2BAA6BwF,EAEhC,IAAK,CACVxF,EAAU,2BAA6B,IACzC,CACF,CCpBgB,SAAAyF,GACdzF,EACA0F,EAAe,CAEd1F,EAA+B,yCAC9B0F,CACJ,CC+CgB,SAAAC,GAAiBpB,EAAmBqB,GAAM,EAAE,CAK1D,OAAAR,GAAa,EAAG,KACdS,GAAc,CAEZ,GAAI,CAACA,EACH,MAAMvH,EAAc,OAAM,qBAAA,GAG9BwH,GAAI,CAEF,MAAMxH,EAAc,OAAM,wBAAA,CAC5B,CAAC,EAEIyH,EAAaC,EAAmBzB,CAAG,EAAG,cAAc,EAAE,aAAY,CAC3E,CAyEgB,SAAAgB,GACdvF,EACAwF,EAAiE,CAEjE,OAAAxF,EAAYgG,EAAmBhG,CAAS,EACjCiG,GAAqBjG,EAA+BwF,CAAc,CAC3E,CAagB,SAAAU,GACdlG,EACA0F,EAAe,CAEf,OAAA1F,EAAYgG,EAAmBhG,CAAS,EACjCyF,GAA6CzF,EAAW0F,CAAM,CACvE,CCzJAT,GAAqB,EC1BrB,KAAK,iBAAiB,UAAYkB,GAAU,CAC1C,QAAQ,IAAI,IAAI,EAChB,QAAQ,IAAIA,CAAK,CACnB,CAAC,EAED,IAAMC,GAAMC,GAAc,CACxB,OAAQ,0CACR,WAAY,gDACZ,YAAa,uDACb,UAAW,gCACX,cAAe,4CACf,kBAAmB,eACnB,MAAO,qCACT,CAAC,EAEDC,GAAY,EAAE,KAAMC,GAAgB,CAClC,GAAIA,EAAa,CACf,IAAMC,EAAYC,GAAaL,EAAG,EAElCM,GAAwDF,EAAW,EAAI,EAEvE,QAAQ,IAAI,sBAAsB,EAElCG,GAAoBH,EAAW,CAAC,CAAE,aAAcI,CAAa,IAAM,CACjE,GAAM,CAAE,MAAAC,EAAO,KAAAC,EAAM,MAAAC,CAAM,EAAIH,GAAgB,CAAC,EAE5C,CAACC,GAIL,KAAK,aAAa,iBAAiBA,EAAO,CACxC,KAAAC,EACA,KAAMC,GAAS,8BACjB,CAAC,CACH,CAAC,CACH,CACF,CAAC", - "names": ["stringToByteArray", "str", "out", "p", "i", "c", "byteArrayToString", "bytes", "pos", "c1", "c2", "c3", "c4", "base64", "input", "webSafe", "byteToCharMap", "output", "byte1", "haveByte2", "byte2", "haveByte3", "byte3", "outByte1", "outByte2", "outByte3", "outByte4", "charToByteMap", "byte4", "base64Encode", "utf8Bytes", "base64urlEncodeWithoutPadding", "Deferred", "resolve", "reject", "callback", "error", "value", "isIndexedDBAvailable", "validateIndexedDBOpenable", "resolve", "reject", "preExist", "DB_CHECK_NAME", "request", "_a", "error", "ERROR_NAME", "FirebaseError", "code", "message", "customData", "ErrorFactory", "service", "serviceName", "errors", "data", "fullCode", "template", "replaceTemplate", "fullMessage", "PATTERN", "_", "key", "value", "deepEqual", "a", "b", "aKeys", "bKeys", "k", "aProp", "bProp", "isObject", "thing", "MAX_VALUE_MILLIS", "getModularInstance", "service", "Component", "name", "instanceFactory", "type", "mode", "multipleInstances", "props", "callback", "DEFAULT_ENTRY_NAME", "Provider", "container", "identifier", "normalizedIdentifier", "deferred", "Deferred", "instance", "options", "optional", "_a", "e", "component", "isComponentEager", "instanceIdentifier", "instanceDeferred", "services", "service", "opts", "normalizedDeferredIdentifier", "existingCallbacks", "existingInstance", "callbacks", "normalizeIdentifierForFactory", "ComponentContainer", "provider", "instances", "LogLevel", "levelStringToEnum", "defaultLogLevel", "ConsoleMethod", "defaultLogHandler", "instance", "logType", "args", "now", "method", "Logger", "name", "val", "instanceOfAny", "object", "constructors", "c", "idbProxyableTypes", "cursorAdvanceMethods", "getIdbProxyableTypes", "getCursorAdvanceMethods", "cursorRequestMap", "transactionDoneMap", "transactionStoreNamesMap", "transformCache", "reverseTransformCache", "promisifyRequest", "request", "promise", "resolve", "reject", "unlisten", "success", "error", "wrap", "value", "cacheDonePromiseForTransaction", "tx", "done", "complete", "idbProxyTraps", "target", "prop", "receiver", "replaceTraps", "callback", "wrapFunction", "func", "storeNames", "args", "unwrap", "transformCachableValue", "newValue", "openDB", "name", "version", "blocked", "upgrade", "blocking", "terminated", "request", "openPromise", "wrap", "event", "db", "deleteDB", "readMethods", "writeMethods", "cachedMethods", "getMethod", "target", "prop", "targetFuncName", "useIndex", "isWrite", "method", "storeName", "args", "tx", "replaceTraps", "oldTraps", "receiver", "PlatformLoggerServiceImpl", "container", "provider", "isVersionServiceProvider", "service", "logString", "component", "logger", "Logger", "DEFAULT_ENTRY_NAME", "PLATFORM_LOG_STRING", "appName", "appCompatName", "analyticsName", "analyticsCompatName", "appCheckName", "appCheckCompatName", "authName", "authCompatName", "databaseName", "databaseCompatName", "functionsName", "functionsCompatName", "installationsName", "installationsCompatName", "messagingName", "messagingCompatName", "performanceName", "performanceCompatName", "remoteConfigName", "remoteConfigCompatName", "storageName", "storageCompatName", "firestoreName", "firestoreCompatName", "packageName", "_apps", "_components", "_addComponent", "app", "component", "e", "logger", "_registerComponent", "component", "componentName", "_components", "logger", "app", "_apps", "_addComponent", "_getProvider", "name", "heartbeatController", "ERRORS", "ERROR_FACTORY", "ErrorFactory", "FirebaseAppImpl", "options", "config", "container", "Component", "val", "initializeApp", "options", "rawConfig", "config", "DEFAULT_ENTRY_NAME", "name", "ERROR_FACTORY", "existingApp", "_apps", "deepEqual", "container", "ComponentContainer", "component", "_components", "newApp", "FirebaseAppImpl", "getApp", "app", "registerVersion", "libraryKeyOrName", "version", "variant", "library", "_a", "PLATFORM_LOG_STRING", "libraryMismatch", "versionMismatch", "warning", "logger", "_registerComponent", "Component", "DB_NAME", "DB_VERSION", "STORE_NAME", "dbPromise", "getDbPromise", "openDB", "db", "oldVersion", "ERROR_FACTORY", "readHeartbeatsFromIndexedDB", "app", "computeKey", "e", "FirebaseError", "logger", "idbGetError", "_a", "writeHeartbeatsToIndexedDB", "heartbeatObject", "tx", "MAX_HEADER_BYTES", "STORED_HEARTBEAT_RETENTION_MAX_MILLIS", "HeartbeatServiceImpl", "container", "HeartbeatStorageImpl", "result", "agent", "date", "getUTCDateString", "singleDateHeartbeat", "hbTimestamp", "heartbeatsToSend", "unsentEntries", "extractHeartbeatsForHeader", "headerString", "base64urlEncodeWithoutPadding", "heartbeatsCache", "maxSize", "heartbeatEntry", "hb", "countBytes", "isIndexedDBAvailable", "validateIndexedDBOpenable", "heartbeatsObject", "existingHeartbeatsObject", "registerCoreComponents", "variant", "_registerComponent", "Component", "PlatformLoggerServiceImpl", "registerVersion", "name", "version", "registerVersion", "name", "version", "PENDING_TIMEOUT_MS", "PACKAGE_VERSION", "version", "INTERNAL_AUTH_VERSION", "INSTALLATIONS_API_URL", "TOKEN_EXPIRATION_BUFFER", "SERVICE", "SERVICE_NAME", "ERROR_DESCRIPTION_MAP", "ERROR_FACTORY", "ErrorFactory", "isServerError", "error", "FirebaseError", "getInstallationsEndpoint", "projectId", "extractAuthTokenInfoFromResponse", "response", "getExpiresInFromResponseExpiresIn", "getErrorFromResponse", "requestName", "errorData", "getHeaders", "apiKey", "getHeadersWithAuth", "appConfig", "refreshToken", "headers", "getAuthorizationHeader", "retryIfServerError", "fn", "result", "responseExpiresIn", "createInstallationRequest", "heartbeatServiceProvider", "fid", "endpoint", "heartbeatService", "heartbeatsHeader", "body", "request", "responseValue", "sleep", "ms", "resolve", "bufferToBase64UrlSafe", "array", "VALID_FID_PATTERN", "INVALID_FID", "generateFid", "fidByteArray", "encode", "getKey", "fidChangeCallbacks", "fidChanged", "key", "callFidChangeCallbacks", "broadcastFidChange", "callFidChangeCallbacks", "key", "fid", "callbacks", "fidChangeCallbacks", "callback", "broadcastFidChange", "channel", "getBroadcastChannel", "closeBroadcastChannel", "broadcastChannel", "DATABASE_NAME", "DATABASE_VERSION", "OBJECT_STORE_NAME", "dbPromise", "getDbPromise", "openDB", "db", "oldVersion", "set", "appConfig", "value", "getKey", "tx", "objectStore", "oldValue", "fidChanged", "remove", "update", "updateFn", "store", "newValue", "getInstallationEntry", "installations", "registrationPromise", "installationEntry", "oldEntry", "updateOrCreateInstallationEntry", "entryWithPromise", "triggerRegistrationIfNecessary", "INVALID_FID", "entry", "generateFid", "clearTimedOutRequest", "registrationPromiseWithError", "ERROR_FACTORY", "inProgressEntry", "registerInstallation", "waitUntilFidRegistration", "registeredInstallationEntry", "createInstallationRequest", "e", "isServerError", "updateInstallationRequest", "sleep", "hasInstallationRequestTimedOut", "PENDING_TIMEOUT_MS", "generateAuthTokenRequest", "heartbeatServiceProvider", "endpoint", "getGenerateAuthTokenEndpoint", "headers", "getHeadersWithAuth", "heartbeatService", "heartbeatsHeader", "body", "PACKAGE_VERSION", "request", "response", "retryIfServerError", "responseValue", "extractAuthTokenInfoFromResponse", "getErrorFromResponse", "getInstallationsEndpoint", "refreshAuthToken", "forceRefresh", "tokenPromise", "isEntryRegistered", "oldAuthToken", "isAuthTokenValid", "waitUntilAuthTokenRequest", "makeAuthTokenRequestInProgressEntry", "fetchAuthTokenFromServer", "updateAuthTokenRequest", "authToken", "hasAuthTokenRequestTimedOut", "updatedInstallationEntry", "isAuthTokenExpired", "now", "TOKEN_EXPIRATION_BUFFER", "inProgressAuthToken", "getId", "installationsImpl", "getToken", "completeInstallationRegistration", "extractAppConfig", "app", "getMissingValueError", "configKeys", "keyName", "valueName", "ERROR_FACTORY", "INSTALLATIONS_NAME", "INSTALLATIONS_NAME_INTERNAL", "publicFactory", "container", "appConfig", "heartbeatServiceProvider", "_getProvider", "internalFactory", "installations", "getId", "forceRefresh", "getToken", "registerInstallations", "_registerComponent", "Component", "registerVersion", "name", "version", "DEFAULT_VAPID_KEY", "ENDPOINT", "FCM_MSG", "CONSOLE_CAMPAIGN_ID", "SDK_PLATFORM_WEB", "EVENT_MESSAGE_DELIVERED", "MessageType", "arrayToBase64", "array", "uint8Array", "base64ToArray", "base64String", "padding", "base64", "rawData", "outputArray", "i", "OLD_DB_NAME", "OLD_DB_VERSION", "OLD_OBJECT_STORE_NAME", "migrateOldDatabase", "senderId", "db", "tokenDetails", "openDB", "oldVersion", "newVersion", "upgradeTransaction", "objectStore", "value", "oldDetails", "_a", "deleteDB", "checkTokenDetails", "subscriptionOptions", "DATABASE_NAME", "DATABASE_VERSION", "OBJECT_STORE_NAME", "dbPromise", "getDbPromise", "upgradeDb", "dbGet", "firebaseDependencies", "key", "getKey", "oldTokenDetails", "dbSet", "tx", "dbRemove", "appConfig", "ERROR_MAP", "ERROR_FACTORY", "ErrorFactory", "requestGetToken", "headers", "getHeaders", "body", "getBody", "subscribeOptions", "responseData", "getEndpoint", "err", "message", "requestUpdateToken", "updateOptions", "requestDeleteToken", "token", "unsubscribeOptions", "projectId", "installations", "authToken", "p256dh", "auth", "endpoint", "vapidKey", "TOKEN_EXPIRATION_MS", "getTokenInternal", "messaging", "pushSubscription", "getPushSubscription", "isTokenValid", "updateToken", "e", "getNewToken", "deleteTokenInternal", "updatedToken", "updatedTokenDetails", "swRegistration", "subscription", "dbOptions", "currentOptions", "isVapidKeyEqual", "isEndpointEqual", "isAuthEqual", "isP256dhEqual", "externalizePayload", "internalPayload", "payload", "propagateNotificationPayload", "propagateDataPayload", "propagateFcmOptions", "messagePayloadInternal", "title", "image", "link", "_c", "_b", "_d", "analyticsLabel", "_e", "isConsoleMessage", "data", "sleep", "ms", "resolve", "_mergeStrings", "stageLog", "fcmEvent", "createFcmEvent", "createAndEnqueueLogEvent", "fid", "logEvent", "s1", "s2", "resultArray", "onSubChange", "event", "newSubscription", "onPush", "getMessagePayloadInternal", "clientList", "getClientList", "hasVisibleClients", "sendMessagePayloadInternalToWindows", "showNotification", "wrapInternalPayload", "onNotificationClick", "getLink", "url", "originUrl", "client", "getWindowClient", "wrappedInternalPayload", "clientUrl", "notificationPayloadInternal", "actions", "maxActions", "extractAppConfig", "app", "getMissingValueError", "configKeys", "options", "keyName", "valueName", "MessagingService", "analyticsProvider", "SwMessagingFactory", "container", "registerMessagingInSw", "_registerComponent", "Component", "isSwSupported", "isIndexedDBAvailable", "validateIndexedDBOpenable", "onBackgroundMessage", "nextOrObserver", "_setDeliveryMetricsExportedToBigQueryEnabled", "enable", "getMessagingInSw", "getApp", "isSupported", "_", "_getProvider", "getModularInstance", "_onBackgroundMessage", "experimentalSetDeliveryMetricsExportedToBigQueryEnabled", "event", "app", "initializeApp", "isSwSupported", "isSupported", "messaging", "getMessagingInSw", "experimentalSetDeliveryMetricsExportedToBigQueryEnabled", "onBackgroundMessage", "notification", "title", "body", "image"] -} From 7c6fe1cefe551a8d39ff6d61d153b6a3dca80903 Mon Sep 17 00:00:00 2001 From: Guillaume Bernos Date: Wed, 5 Oct 2022 10:09:52 +0200 Subject: [PATCH 10/13] feat(messaging): revert to old service worker with compat --- .../test_driver/firebase_messaging/firebase_messaging_e2e.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/test_driver/firebase_messaging/firebase_messaging_e2e.dart b/tests/test_driver/firebase_messaging/firebase_messaging_e2e.dart index 7ee6300d52aa..860e342911c1 100644 --- a/tests/test_driver/firebase_messaging/firebase_messaging_e2e.dart +++ b/tests/test_driver/firebase_messaging/firebase_messaging_e2e.dart @@ -218,6 +218,8 @@ void setupTests() { () async { await messaging.setDeliveryMetricsExportToBigQuery(true); }, + // Web is skipped because it has to be setup in the service worker + skip: kIsWeb, ); }); }, From 7d46e8c0f38127eb89613a2cbe26222b186abf04 Mon Sep 17 00:00:00 2001 From: Guillaume Bernos Date: Wed, 5 Oct 2022 11:16:07 +0200 Subject: [PATCH 11/13] feat(messaging): revert to old service worker with compat --- docs/cloud-messaging/receive.md | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/docs/cloud-messaging/receive.md b/docs/cloud-messaging/receive.md index 027451a5638f..8e3ea4fa8937 100644 --- a/docs/cloud-messaging/receive.md +++ b/docs/cloud-messaging/receive.md @@ -351,7 +351,7 @@ the API or the Notifications composer. To enable the export, first follow the steps [described here](https://firebase.google.com/docs/cloud-messaging/understand-delivery?platform=ios#bigquery-data-export), then follow these instructions: -### Android and Web +### Android You can use the following code: ```dart @@ -383,4 +383,20 @@ For iOS, you need to change the `AppDelegate.m` with the following content. } @end -``` \ No newline at end of file +``` + +### Web + +For Web, you need to change your service worker in order to use the v9 version of the SDK. +The v9 version needs to be bundled, so you need to use a bundler like `esbuild` for instance +to get the service worker to work. +See [the example app](https://github.com/firebase/flutterfire/blob/master/packages/firebase_messaging/firebase_messaging/example/bundled-service-worker) to see how to achieve this. + +Once you've migrated to the v9 SDK, you can use the following code: + +``` typescript +const messaging = getMessaging(app); +experimentalSetDeliveryMetricsExportedToBigQueryEnabled(messaging, true); +``` + +Don't forget to run `yarn build` in order to export the new version of your service worker to the `web` folder. \ No newline at end of file From 29a539904e46feab5dd565e23221eaa47e080d97 Mon Sep 17 00:00:00 2001 From: Guillaume Bernos Date: Thu, 6 Oct 2022 10:00:15 +0200 Subject: [PATCH 12/13] feat(messaging): export to BigQuery --- .../src/platform_interface/platform_interface_messaging.dart | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/firebase_messaging/firebase_messaging_platform_interface/lib/src/platform_interface/platform_interface_messaging.dart b/packages/firebase_messaging/firebase_messaging_platform_interface/lib/src/platform_interface/platform_interface_messaging.dart index c09f12a674f2..7ef3abd30c58 100644 --- a/packages/firebase_messaging/firebase_messaging_platform_interface/lib/src/platform_interface/platform_interface_messaging.dart +++ b/packages/firebase_messaging/firebase_messaging_platform_interface/lib/src/platform_interface/platform_interface_messaging.dart @@ -307,6 +307,10 @@ abstract class FirebaseMessagingPlatform extends PlatformInterface { } /// Enables or disables Firebase Cloud Messaging message delivery metrics export to BigQuery. + /// + /// On iOS, you need to follow [this guide](https://firebase.google.com/docs/cloud-messaging/understand-delivery?platform=ios#enable_delivery_data_export_for_background_notifications) + /// in order to export metrics to BigQuery. + /// On Web, you need to setup a [service worker](https://firebase.google.com/docs/cloud-messaging/js/client) and call `experimentalSetDeliveryMetricsExportedToBigQueryEnabled(messaging, true)` Future setDeliveryMetricsExportToBigQuery(bool enabled) { throw UnimplementedError( 'setDeliveryMetricsExportToBigQuery() is not implemented', From 32fca9273a7411a4b5e7a70400d4b74c5bb9d2f4 Mon Sep 17 00:00:00 2001 From: Guillaume Bernos Date: Thu, 6 Oct 2022 14:55:53 +0200 Subject: [PATCH 13/13] feat(messaging): export to BigQuery --- docs/cloud-messaging/receive.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/cloud-messaging/receive.md b/docs/cloud-messaging/receive.md index 8e3ea4fa8937..d5721387e03e 100644 --- a/docs/cloud-messaging/receive.md +++ b/docs/cloud-messaging/receive.md @@ -395,6 +395,13 @@ See [the example app](https://github.com/firebase/flutterfire/blob/master/packag Once you've migrated to the v9 SDK, you can use the following code: ``` typescript +import { + experimentalSetDeliveryMetricsExportedToBigQueryEnabled, + getMessaging, +} from 'firebase/messaging/sw'; + +... + const messaging = getMessaging(app); experimentalSetDeliveryMetricsExportedToBigQueryEnabled(messaging, true); ```